diff --git a/cmd/makedocs/main.go b/cmd/makedocs/main.go index 5ee8ef524..671e48a55 100644 --- a/cmd/makedocs/main.go +++ b/cmd/makedocs/main.go @@ -1,5 +1,3 @@ -//+build ignore - package main import ( @@ -8,7 +6,8 @@ import ( "log" "text/template" - "github.com/go-critic/go-critic/lint" + _ "github.com/go-critic/go-critic/checkers" + "github.com/go-lintpack/lintpack" ) const ( @@ -20,9 +19,9 @@ func main() { tmpl := template.Must(template.ParseFiles(templatesPath + "overview.md.tmpl")) buf := bytes.Buffer{} err := tmpl.Execute(&buf, struct { - Rules []*lint.Rule + Checkers []*lintpack.CheckerInfo }{ - Rules: lint.RuleList(), + Checkers: lintpack.GetCheckersInfo(), }) if err != nil { log.Fatalf("render template: %v", err) diff --git a/docs/overview.md b/docs/overview.md index 7399eb644..7efadfd44 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -11,265 +11,260 @@ This page describes checks supported by [go-critic](https://github.com/go-critic Name Short description - - appendCombine - Detects `append` chains to the same slice that can be done in a single `append` call - - - builtinShadow - Detects when predeclared identifiers shadowed in assignments - - - flagDeref - Detects immediate dereferencing of `flag` package pointers - - - ifElseChain - Detects repeated if-else statements and suggests to replace them with switch statement - - - paramTypeCombine :nerd_face: - Detects if function parameters could be combined by type and suggest the way to do it - - - rangeExprCopy - Detects expensive copies of `for` loop range expressions - - - rangeValCopy - Detects loops that copy big objects during each iteration - - - regexpMust - Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*` - - - singleCaseSwitch - Detects switch statements that could be better written as if statements - - - switchTrue - Detects switch-over-bool statements that use explicit `true` tag value - - - typeSwitchVar - Detects type switches that can benefit from type guard clause with variable - - - typeUnparen - Detects unneded parenthesis inside type expressions and suggests to remove them - - - underef - Detects dereference expressions that can be omitted - - - unslice - Detects slice expressions that can be simplified to sliced expression itself - + + appendAssign + Detects suspicious append result assignments + + + appendCombine + Detects `append` chains to the same slice that can be done in a single `append` call + + + argOrder + Detects suspicious arguments order + + + assignOp + Detects assignments that can be simplified by using assignment operators + + + badCond + Detects suspicious condition expressions + + + boolExprSimplify + Detects bool expressions that can be simplified + + + builtinShadow + Detects when predeclared identifiers shadowed in assignments + + + captLocal + Detects capitalized names for local variables + + + caseOrder + Detects erroneous case order inside switch statements + + + codegenComment + Detects malformed 'code generated' file comments + + + commentFormatting + Detects comments with non-idiomatic formatting + + + commentedOutCode + Detects commented-out code inside function bodies + + + commentedOutImport + Detects commented-out imports + + + defaultCaseOrder + Detects when default case in switch isn't on 1st or last position + + + deprecatedComment + Detects malformed 'deprecated' doc-comments + + + docStub + Detects comments that silence go lint complaints about doc-comment + + + dupArg + Detects suspicious duplicated arguments + + + dupBranchBody + Detects duplicated branch bodies inside conditional statements + + + dupCase + Detects duplicated case clauses inside switch statements + + + dupSubExpr + Detects suspicious duplicated sub-expressions + + + elseif + Detects else with nested if statement that can be replaced with else-if + + + emptyFallthrough + Detects fallthrough that can be avoided by using multi case values + + + emptyStringTest + Detects empty string checks that can be written more idiomatically + + + equalFold + Detects unoptimal strings/bytes case-insensitive comparison + + + exitAfterDefer + Detects calls to exit/fatal inside functions that use defer + + + flagDeref + Detects immediate dereferencing of `flag` package pointers + + + flagName + Detects flag names with whitespace + + + hexLiteral + Detects hex literals that have mixed case letter digits + + + hugeParam + Detects params that incur excessive amount of copying + + + ifElseChain + Detects repeated if-else statements and suggests to replace them with switch statement + + + importShadow + Detects when imported package names shadowed in the assignments + + + indexAlloc + Detects strings.Index calls that may cause unwanted allocs + + + initClause + Detects non-assignment statements inside if/switch init clause + + + methodExprCall + Detects method expression call that can be replaced with a method call + + + nestingReduce + Finds where nesting level could be reduced + + + nilValReturn + Detects return statements those results evaluate to nil + + + offBy1 + Detects various off-by-one kind of errors + + + paramTypeCombine + Detects if function parameters could be combined by type and suggest the way to do it + + + ptrToRefParam + Detects input and output parameters that have a type of pointer to referential type + + + rangeExprCopy + Detects expensive copies of `for` loop range expressions + + + rangeValCopy + Detects loops that copy big objects during each iteration + + + regexpMust + Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*` + + + singleCaseSwitch + Detects switch statements that could be better written as if statement + + + sloppyLen + Detects usage of `len` when result is obvious or doesn't make sense + + + sloppyReassign + Detects suspicious/confusing re-assignments + + + stringXbytes + Detects redundant conversions between string and []byte + + + switchTrue + Detects switch-over-bool statements that use explicit `true` tag value + + + typeAssertChain + Detects repeated type assertions and suggests to replace them with type switch statement + + + typeSwitchVar + Detects type switches that can benefit from type guard clause with variable + + + typeUnparen + Detects unneded parenthesis inside type expressions and suggests to remove them + + + underef + Detects dereference expressions that can be omitted + + + unlabelStmt + Detects redundant statement labels + + + unlambda + Detects function literals that can be simplified + + + unnamedResult + Detects unnamed results that may benefit from names + + + unnecessaryBlock + Detects unnecessary braced statement blocks + + + unslice + Detects slice expressions that can be simplified to sliced expression itself + + + valSwap + Detects value swapping code that are not using parallel assignment + + + weakCond + Detects conditions that are unsafe due to not being exhaustive + + + wrapperFunc + Detects function calls that can be replaced with convenience wrappers + + + yodaStyleExpr + Detects Yoda style expressions and suggests to replace them + -**Experimental:** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameShort description
appendAssignDetects suspicious append result assignments
assignOpDetects assignments that can be simplified by using assignment operators
blankParam :nerd_face:Detects unused params and suggests to name them as `_` (blank)
boolExprSimplifyDetects bool expressions that can be simplified
boolFuncPrefix :nerd_face:Detects function returning only bool and suggests to add Is/Has/Contains prefix to it's name
busySelectDetects default statement inside a select without a sleep that might waste a CPU time
captLocalDetects capitalized names for local variables
caseOrderDetects erroneous case order inside switch statements
commentedOutCodeDetects commented-out code inside function bodies
deadCodeAfterLogFatalDetects dead code that follow panic/fatal logging
defaultCaseOrderDetects when default case in switch isn't on 1st or last position
deferInLoopDetects defer in loop and warns that it will not be executed till the end of function's scope
deprecatedCommentDetects malformed "deprecated" doc-comments
docStubDetects comments that silence go lint complaints about doc-comment
dupArgDetects suspicious duplicated arguments
dupBranchBodyDetects duplicated branch bodies inside conditional statements
dupCaseDetects duplicated case clauses inside switch statements
dupSubExprDetects suspicious duplicated sub-expressions
elseif :nerd_face:Detects else with nested if statement that can be replaced with else-if
emptyFallthroughDetects fallthrough that can be avoided by using multi case values
emptyFmtDetects usages of formatting functions without formatting arguments
evalOrderDetects potentially unsafe dependencies on evaluation order
flagNameDetects flag names with whitespace
floatCompareDetects fragile float variables comparisons
hugeParamDetects params that incur excessive amount of copying
importPackageNameDetects when imported package names are unnecessary renamed
importShadowDetects when imported package names shadowed in assignments
indexAllocDetects strings.Index calls that may cause unwanted allocs
indexOnlyLoopDetects for loops that can benefit from rewrite to range loop
initClauseDetects non-assignment statements inside if/switch init clause
longChain :nerd_face:Detects repeated expression chains and suggest to refactor them
methodExprCall :nerd_face:Detects method expression call that can be replaced with a method call
namedConstDetects literals that can be replaced with defined named const
nestingReduceFinds where nesting level could be reduced
nilValReturnDetects return statements those results evaluate to nil
ptrToRefParamDetects input and output parameters that have a type of pointer to referential type
sloppyLenDetects usage of `len` when result is obvious or doesn't make sense
sqlRowsCloseDetects uses of *sql.Rows without call Close method
stdExprDetects constant expressions that can be replaced by a stdlib const
structLitKeyOrder :nerd_face:Detects struct literal keys order that does not match declaration order
unexportedCall :nerd_face:Detects calls of unexported method from unexported type outside that type
unlabelStmtDetects redundant statement labels
unlambdaDetects function literals that can be simplified
unnamedResultDetects unnamed results that may benefit from names
unnecessaryBlockDetects unnecessary braced statement blocks
yodaStyleExpr :nerd_face:Detects Yoda style expressions and suggests to replace them
- - ## appendAssign + +[ + **diagnostic** ] + Detects suspicious append result assignments. + **Before:** ```go p.positives = append(p.negatives, x) @@ -283,13 +278,17 @@ p.negatives = append(p.negatives, y) ``` - ## appendCombine + +[ + **performance** ] + Detects `append` chains to the same slice that can be done in a single `append` call. + **Before:** ```go xs = append(xs, 1) @@ -302,13 +301,40 @@ xs = append(xs, 1, 2) ``` + +## argOrder + +[ + **diagnostic** + **experimental** ] + +Detects suspicious arguments order. + + + + +**Before:** +```go +strings.HasPrefix("#", userpass) +``` + +**After:** +```go +strings.HasPrefix(userpass, "#") +``` + ## assignOp + +[ + **style** ] + Detects assignments that can be simplified by using assignment operators. + **Before:** ```go x = x * 2 @@ -320,31 +346,45 @@ x *= 2 ``` + +## badCond + +[ + **diagnostic** + **experimental** ] + +Detects suspicious condition expressions. - -## blankParam -Detects unused params and suggests to name them as `_` (blank). **Before:** ```go -func f(a int, b float64) // b isn't used inside function body +for i := 0; i > n; i++ { + xs[i] = 0 +} ``` **After:** ```go -func f(a int, _ float64) // everything is cool +for i := 0; i < n; i++ { + xs[i] = 0 +} ``` -`blankParam` is very opinionated. ## boolExprSimplify + +[ + **style** + **experimental** ] + Detects bool expressions that can be simplified. + **Before:** ```go a := !(elapsed >= expectElapsedMin) @@ -358,129 +398,141 @@ b := (x) == (y) ``` + +## builtinShadow + +[ + **style** + **opinionated** ] + +Detects when predeclared identifiers shadowed in assignments. - -## boolFuncPrefix -Detects function returning only bool and suggests to add Is/Has/Contains prefix to it's name. **Before:** ```go -func Enabled() bool +len := 10 ``` **After:** ```go -func IsEnabled() bool +length := 10 ``` -`boolFuncPrefix` is very opinionated. - -## builtinShadow -Detects when predeclared identifiers shadowed in assignments. + +## captLocal + +[ + **style** ] + +Detects capitalized names for local variables. + **Before:** ```go -len := 10 -println(len) +func f(IN int, OUT *int) (ERR error) {} ``` **After:** ```go -length := 10 // Changed variable name -println(length) +func f(in int, out *int) (err error) {} ``` -`builtinShadow` is syntax-only checker (fast). - -## busySelect -Detects default statement inside a select without a sleep that might waste a CPU time. + +## caseOrder + +[ + **diagnostic** ] + +Detects erroneous case order inside switch statements. + **Before:** ```go -for { - select { - case <-ch: - // ... - default: - // will waste CPU time - } +switch x.(type) { +case ast.Expr: + fmt.Println("expr") +case *ast.BasicLit: + fmt.Println("basic lit") // Never executed } ``` **After:** ```go -for { - select { - case <-ch: - // ... - default: - time.Sleep(100 * time.Millisecond) - } +switch x.(type) { +case *ast.BasicLit: + fmt.Println("basic lit") // Now reachable +case ast.Expr: + fmt.Println("expr") } ``` + +## codegenComment + +[ + **diagnostic** + **experimental** ] + +Detects malformed 'code generated' file comments. - -## captLocal -Detects capitalized names for local variables. **Before:** ```go -func f(IN int, OUT *int) (ERR error) {} +// This file was automatically generated by foogen ``` **After:** ```go -func f(in int, out *int) (err error) {} +// Code generated by foogen. DO NOT EDIT. ``` -`captLocal` is syntax-only checker (fast). - -## caseOrder -Detects erroneous case order inside switch statements. + +## commentFormatting + +[ + **style** + **experimental** ] + +Detects comments with non-idiomatic formatting. + **Before:** ```go -switch x.(type) { -case ast.Expr: - fmt.Println("expr") -case *ast.BasicLit: - fmt.Println("basic lit") // Never executed -} +//This is a comment ``` **After:** ```go -switch x.(type) { -case *ast.BasicLit: - fmt.Println("basic lit") // Now reachable -case ast.Expr: - fmt.Println("expr") -} +// This is a comment ``` - ## commentedOutCode + +[ + **diagnostic** + **experimental** ] + Detects commented-out code inside function bodies. + **Before:** ```go // fmt.Println("Debugging hard") @@ -493,32 +545,45 @@ foo(1, 2) ``` + +## commentedOutImport + +[ + **style** + **experimental** ] + +Detects commented-out imports. - -## deadCodeAfterLogFatal -Detects dead code that follow panic/fatal logging. **Before:** ```go -log.Fatal("exits function") -return +import ( + "fmt" + //"os" +) ``` **After:** ```go -log.Fatal("exits function") +import ( + "fmt" +) ``` - ## defaultCaseOrder + +[ + **style** ] + Detects when default case in switch isn't on 1st or last position. + **Before:** ```go switch { @@ -544,34 +609,15 @@ default: // <- last case (could also be the first one) ``` -`defaultCaseOrder` is syntax-only checker (fast). - -## deferInLoop -Detects defer in loop and warns that it will not be executed till the end of function's scope. - - - -**Before:** -```go -for i := range [10]int{} { - defer f(i) // will be executed only at the end of func -} -``` - -**After:** -```go -for i := range [10]int{} { - func(i int) { - defer f(i) - }(i) -} -``` + +## deprecatedComment +[ + **diagnostic** + **experimental** ] +Detects malformed 'deprecated' doc-comments. - -## deprecatedComment -Detects malformed "deprecated" doc-comments. @@ -588,13 +634,18 @@ func FuncOld() int ``` -`deprecatedComment` is syntax-only checker (fast). ## docStub + +[ + **style** + **experimental** ] + Detects comments that silence go lint complaints about doc-comment. + **Before:** ```go // Foo ... @@ -604,19 +655,25 @@ func Foo() { **After:** ```go -func Foo() { -} +// (A) - remove the doc-comment stub +func Foo() {} +// (B) - replace it with meaningful comment +// Foo is a demonstration-only function. +func Foo() {} ``` -You can either remove a comment to let go lint find it or change stub to useful comment. -This checker makes it easier to detect stubs, the action is up to you. -`docStub` is syntax-only checker (fast). + ## dupArg + +[ + **diagnostic** ] + Detects suspicious duplicated arguments. + **Before:** ```go copy(dst, dst) @@ -628,13 +685,17 @@ copy(dst, src) ``` - ## dupBranchBody + +[ + **diagnostic** ] + Detects duplicated branch bodies inside conditional statements. + **Before:** ```go if cond { @@ -654,13 +715,17 @@ if cond { ``` - ## dupCase + +[ + **diagnostic** ] + Detects duplicated case clauses inside switch statements. + **Before:** ```go switch x { @@ -676,13 +741,17 @@ case ys[0], ys[1], ys[2], ys[3], ys[4]: ``` - ## dupSubExpr + +[ + **diagnostic** ] + Detects suspicious duplicated sub-expressions. + **Before:** ```go sort.Slice(xs, func(i, j int) bool { @@ -698,13 +767,17 @@ sort.Slice(xs, func(i, j int) bool { ``` - ## elseif + +[ + **style** ] + Detects else with nested if statement that can be replaced with else-if. + **Before:** ```go if cond1 { @@ -722,13 +795,18 @@ if cond1 { ``` -`elseif` is very opinionated. ## emptyFallthrough + +[ + **style** + **experimental** ] + Detects fallthrough that can be avoided by using multi case values. + **Before:** ```go switch kind { @@ -748,54 +826,93 @@ case reflect.Int, reflect.Int32: ``` + +## emptyStringTest + +[ + **style** + **experimental** ] + +Detects empty string checks that can be written more idiomatically. - -## emptyFmt -Detects usages of formatting functions without formatting arguments. **Before:** ```go -fmt.Sprintf("whatever") -fmt.Errorf("wherever") +len(s) == 0 ``` **After:** ```go -fmt.Sprint("whatever") -errors.New("wherever") +s == "" ``` +**Note:** +See https://dmitri.shuralyov.com/idiomatic-go#empty-string-check. + +## equalFold + +[ + **performance** + **experimental** ] + +Detects unoptimal strings/bytes case-insensitive comparison. - -## evalOrder -Detects potentially unsafe dependencies on evaluation order. **Before:** ```go -return mayModifySlice(&xs), xs[0] +strings.ToLower(x) == strings.ToLower(y) ``` **After:** ```go -// A) -v := mayModifySlice(&xs) -return v, xs[0] -// B) -v := xs[0] -return mayModifySlice(&xs), v +strings.EqualFold(x, y) ``` + +## exitAfterDefer + +[ + **diagnostic** + **experimental** ] + +Detects calls to exit/fatal inside functions that use defer. + + + + +**Before:** +```go +defer os.Remove(filename) +if bad { + log.Fatalf("something bad happened") +} +``` + +**After:** +```go +defer os.Remove(filename) +if bad { + log.Printf("something bad happened") + return +} +``` + ## flagDeref + +[ + **diagnostic** ] + Detects immediate dereferencing of `flag` package pointers. +Suggests to use pointer to array to avoid the copy using `&` on range expression. **Before:** @@ -809,15 +926,22 @@ var b bool flag.BoolVar(&b, "b", false, "b docs") ``` + +**Note:** Dereferencing returned pointers will lead to hard to find errors where flag values are not updated after flag.Parse(). -`flagDeref` is syntax-only checker (fast). ## flagName + +[ + **diagnostic** + **experimental** ] + Detects flag names with whitespace. + **Before:** ```go b := flag.Bool(" foo ", false, "description") @@ -829,33 +953,45 @@ b := flag.Bool("foo", false, "description") ``` + +## hexLiteral + +[ + **style** + **experimental** ] + +Detects hex literals that have mixed case letter digits. - -## floatCompare -Detects fragile float variables comparisons. **Before:** ```go -// x and y are floats -return x == y +x := 0X12 +y := 0xfF ``` **After:** ```go -// x and y are floats -return math.Abs(x - y) < eps +x := 0x12 +// (A) +y := 0xff +// (B) +y := 0xFF ``` - ## hugeParam + +[ + **performance** ] + Detects params that incur excessive amount of copying. + **Before:** ```go func f(x [1024]int) {} @@ -867,13 +1003,17 @@ func f(x *[1024]int) {} ``` - ## ifElseChain + +[ + **style** ] + Detects repeated if-else statements and suggests to replace them with switch statement. + **Before:** ```go if cond1 { @@ -897,99 +1037,72 @@ default: } ``` + +**Note:** 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). -`ifElseChain` is syntax-only checker (fast). - -## importPackageName -Detects when imported package names are unnecessary renamed. - - - -**Before:** -```go -import lint "github.com/go-critic/go-critic/lint" -``` - -**After:** -```go -import "github.com/go-critic/go-critic/lint" -``` + +## importShadow +[ + **style** + **opinionated** ] +Detects when imported package names shadowed in the assignments. - -## importShadow -Detects when imported package names shadowed in assignments. **Before:** ```go // "path/filepath" is imported. -func myFunc(filepath string) { -} +filepath := "foo.txt" ``` **After:** ```go -func myFunc(filename string) { -} +filename := "foo.txt" ``` - ## indexAlloc -Detects strings.Index calls that may cause unwanted allocs. +[ + **performance** ] +Detects strings.Index calls that may cause unwanted allocs. -**Before:** -```go -strings.Index(string(x), y) -``` - -**After:** -```go -bytes.Index(x, []byte(y)) -``` - -See Go issue for details: https://github.com/golang/go/issues/25864 - -## indexOnlyLoop -Detects for loops that can benefit from rewrite to range loop. -Suggests to use for key, v := range container form. **Before:** ```go -for i := range files { - if files[i] != nil { - files[i].Close() - } -} +strings.Index(string(x), y) ``` **After:** ```go -for _, f := range files { - if f != nil { - f.Close() - } -} +bytes.Index(x, []byte(y)) ``` - +**Note:** +See Go issue for details: https://github.com/golang/go/issues/25864 ## initClause + +[ + **style** + **opinionated** + **experimental** ] + Detects non-assignment statements inside if/switch init clause. + **Before:** ```go if sideEffect(); cond { @@ -1004,39 +1117,18 @@ if cond { ``` -`initClause` is syntax-only checker (fast). - -## longChain -Detects repeated expression chains and suggest to refactor them. - - - -**Before:** -```go -a := q.w.e.r.t + 1 -b := q.w.e.r.t + 2 -c := q.w.e.r.t + 3 -v := (a + xs[i+1]) + (b + xs[i+1]) + (c + xs[i+1]) -``` - -**After:** -```go -x := xs[i+1] -qwert := q.w.e.r.t -a := qwert + 1 -b := qwert + 2 -c := qwert + 3 -v := (a + x) + (b + x) + (c + x) -``` - - -`longChain` is very opinionated. ## methodExprCall + +[ + **style** + **experimental** ] + Detects method expression call that can be replaced with a method call. + **Before:** ```go f := foo{} @@ -1050,32 +1142,19 @@ f.bar() ``` -`methodExprCall` is very opinionated. - -## namedConst -Detects literals that can be replaced with defined named const. - - - -**Before:** -```go -// pos has type of token.Pos. -return pos != 0 -``` - -**After:** -```go -return pos != token.NoPos -``` - - - ## nestingReduce + +[ + **style** + **opinionated** + **experimental** ] + Finds where nesting level could be reduced. + **Before:** ```go for _, v := range a { @@ -1096,13 +1175,18 @@ for _, v := range a { ``` - ## nilValReturn + +[ + **diagnostic** + **experimental** ] + Detects return statements those results evaluate to nil. + **Before:** ```go if err == nil { @@ -1123,13 +1207,41 @@ if err != nil { ``` + +## offBy1 + +[ + **diagnostic** + **experimental** ] + +Detects various off-by-one kind of errors. + + + + +**Before:** +```go +xs[len(xs)] +``` + +**After:** +```go +xs[len(xs)-1] +``` + ## paramTypeCombine + +[ + **style** + **opinionated** ] + Detects if function parameters could be combined by type and suggest the way to do it. + **Before:** ```go func foo(a, b int, c, d int, e, f int, g int) {} @@ -1141,13 +1253,19 @@ func foo(a, b, c, d, e, f, g int) {} ``` -`paramTypeCombine` is syntax-only checker (fast).`paramTypeCombine` is very opinionated. ## ptrToRefParam + +[ + **style** + **opinionated** + **experimental** ] + Detects input and output parameters that have a type of pointer to referential type. + **Before:** ```go func f(m *map[string]int) (*chan *int) @@ -1159,13 +1277,17 @@ func f(m map[string]int) (chan *int) ``` - ## rangeExprCopy + +[ + **performance** ] + Detects expensive copies of `for` loop range expressions. Suggests to use pointer to array to avoid the copy using `&` on range expression. + **Before:** ```go var xs [2048]byte @@ -1182,14 +1304,20 @@ for _, x := range &xs { // No copy } ``` -See Go issue for details: https://github.com/golang/go/issues/15812 +**Note:** +See Go issue for details: https://github.com/golang/go/issues/15812. ## rangeValCopy + +[ + **performance** ] + Detects loops that copy big objects during each iteration. Suggests to use index access or take address and make use pointer instead. + **Before:** ```go xs := make([][1024]byte, length) @@ -1208,13 +1336,17 @@ for i := range xs { ``` - ## regexpMust + +[ + **style** ] + Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*`. + **Before:** ```go re, _ := regexp.Compile("const pattern") @@ -1226,10 +1358,14 @@ re := regexp.MustCompile("const pattern") ``` - ## singleCaseSwitch -Detects switch statements that could be better written as if statements. + +[ + **style** ] + +Detects switch statements that could be better written as if statement. + @@ -1249,13 +1385,17 @@ if x, ok := x.(int); ok { ``` -`singleCaseSwitch` is syntax-only checker (fast). ## sloppyLen + +[ + **style** ] + Detects usage of `len` when result is obvious or doesn't make sense. + **Before:** ```go len(arr) >= 0 // Sloppy @@ -1270,98 +1410,125 @@ len(arr) == 0 ``` -`sloppyLen` is syntax-only checker (fast). - -## sqlRowsClose -Detects uses of *sql.Rows without call Close method. + +## sloppyReassign + +[ + **diagnostic** + **experimental** ] + +Detects suspicious/confusing re-assignments. + **Before:** ```go -rows, _ := db.Query( /**/ ) -for rows.Next { -} +if err = f(); err != nil { return err } ``` **After:** ```go -rows, _ := db.Query( /**/ ) -for rows.Next { -} -rows.Close() +if err := f(); err != nil { return err } ``` + +## stringXbytes + +[ + **style** + **experimental** ] + +Detects redundant conversions between string and []byte. - -## stdExpr -Detects constant expressions that can be replaced by a stdlib const. **Before:** ```go -intBytes := make([]byte, unsafe.Sizeof(0)) -maxVal := 1<<7 - 1 +copy(b, []byte(s)) ``` **After:** ```go -intBytes := make([]byte, bits.IntSize) -maxVal := math.MaxInt8 +copy(b, s) ``` + +## switchTrue + +[ + **style** ] + +Detects switch-over-bool statements that use explicit `true` tag value. - -## structLitKeyOrder -Detects struct literal keys order that does not match declaration order. **Before:** ```go -type foo struct{ x, y int } -v := foo{y: y, x: x} +switch true { +case x > y: +} ``` **After:** ```go -type foo struct{ x, y int } -v := foo{x: x, y: y} +switch { +case x > y: +} ``` -`structLitKeyOrder` is very opinionated. - -## switchTrue -Detects switch-over-bool statements that use explicit `true` tag value. + +## typeAssertChain + +[ + **style** + **experimental** ] + +Detects repeated type assertions and suggests to replace them with type switch statement. + **Before:** ```go -switch true { -case x > y: +if x, ok := v.(T1); ok { + // Code A, uses x. +} else if x, ok := v.(T2); ok { + // Code B, uses x. +} else if x, ok := v.(T3); ok { + // Code C, uses x. } ``` **After:** ```go -switch { -case x > y: +switch x := v.(T1) { +case cond1: + // Code A, uses x. +case cond2: + // Code B, uses x. +default: + // Code C, uses x. } ``` -`switchTrue` is syntax-only checker (fast). ## typeSwitchVar + +[ + **style** ] + Detects type switches that can benefit from type guard clause with variable. + **Before:** ```go switch v.(type) { @@ -1387,13 +1554,18 @@ default: ``` - ## typeUnparen + +[ + **style** + **opinionated** ] + Detects unneded parenthesis inside type expressions and suggests to remove them. + **Before:** ```go type foo [](func([](func()))) @@ -1405,13 +1577,17 @@ type foo []func([]func()) ``` -`typeUnparen` is syntax-only checker (fast). ## underef + +[ + **style** ] + Detects dereference expressions that can be omitted. + **Before:** ```go (*k).field = 5 @@ -1425,35 +1601,18 @@ v := a[5] ``` - - -## unexportedCall -Detects calls of unexported method from unexported type outside that type. - - - -**Before:** -```go -func baz(f foo) { - fo.bar() -} -``` - -**After:** -```go -func baz(f foo) { - fo.Bar() // Made method exported -} -``` - - -`unexportedCall` is very opinionated. ## unlabelStmt + +[ + **style** + **experimental** ] + Detects redundant statement labels. + **Before:** ```go derp: @@ -1474,13 +1633,17 @@ for x := range xs { ``` - ## unlambda + +[ + **style** ] + Detects function literals that can be simplified. + **Before:** ```go func(x int) int { return fn(x) } @@ -1492,13 +1655,19 @@ fn ``` - ## unnamedResult + +[ + **style** + **opinionated** + **experimental** ] + Detects unnamed results that may benefit from names. + **Before:** ```go func f() (float64, float64) @@ -1510,13 +1679,19 @@ func f() (x, y float64) ``` - ## unnecessaryBlock + +[ + **style** + **opinionated** + **experimental** ] + Detects unnecessary braced statement blocks. + **Before:** ```go x := 1 @@ -1532,13 +1707,17 @@ print(x) ``` -`unnecessaryBlock` is syntax-only checker (fast). ## unslice + +[ + **style** ] + Detects slice expressions that can be simplified to sliced expression itself. + **Before:** ```go f(s[:]) // s is string @@ -1552,13 +1731,89 @@ copy(b, values...) ``` + +## valSwap + +[ + **style** + **experimental** ] + +Detects value swapping code that are not using parallel assignment. + + + + +**Before:** +```go +tmp := *x +*x = *y +*y = tmp +``` + +**After:** +```go +*x, *y = *y, *x +``` + + + +## weakCond + +[ + **diagnostic** + **experimental** ] + +Detects conditions that are unsafe due to not being exhaustive. + + + + +**Before:** +```go +xs != nil && xs[0] != nil +``` + +**After:** +```go +len(xs) != 0 && xs[0] != nil +``` + + + +## wrapperFunc + +[ + **style** + **experimental** ] + +Detects function calls that can be replaced with convenience wrappers. + + + + +**Before:** +```go +wg.Add(-1) +``` + +**After:** +```go +wg.Done() +``` + ## yodaStyleExpr + +[ + **style** + **experimental** ] + Detects Yoda style expressions and suggests to replace them. + **Before:** ```go return nil != ptr @@ -1570,4 +1825,3 @@ return ptr != nil ``` -`yodaStyleExpr` is very opinionated. \ No newline at end of file diff --git a/docs/templates/overview.md.tmpl b/docs/templates/overview.md.tmpl index a34d5fa44..efb7269f1 100644 --- a/docs/templates/overview.md.tmpl +++ b/docs/templates/overview.md.tmpl @@ -2,8 +2,6 @@ This page describes checks supported by [go-critic](https://github.com/go-critic/go-critic) linter. -Checkers marked with a :nerd_face: are opinionated. They may be not suitable for everyone. - [//]: # (This is generated file, please don't edit it yourself.) ## Checkers: @@ -13,56 +11,39 @@ Checkers marked with a :nerd_face: are opinionated. They may be not suitable for Name Short description - {{- range .Rules }} - {{- if not .Experimental }} - - {{.Name}}{{ if .VeryOpinionated }} :nerd_face:{{ end }} - {{.Doc.Summary}} - - {{- end }} + {{- range .Checkers }} + + {{.Name}} + {{.Summary}} + {{- end }} -**Experimental:** +{{ range .Checkers }} + +## {{ .Name }} - - - - - - {{- range .Rules }} - {{- if .Experimental }} - - - - - {{- end }} - {{- end }} -
NameShort description
{{ .Name }}{{ if .VeryOpinionated }} :nerd_face:{{ end }}{{.Doc.Summary}}
+[{{ range $tag := .Tags }} + **{{ $tag }}** +{{- end }} ] +{{ .Summary -}}. -{{ range .Rules }} - -## {{ .Name }} -{{ .Doc.Summary -}}. +{{ .Details }} -{{ .Doc.Details }} **Before:** ```go -{{ .Doc.Before }} +{{ .Before }} ``` **After:** ```go -{{ .Doc.After }} +{{ .After }} ``` -{{ .Doc.Note }} -{{ if .SyntaxOnly -}} - `{{.Name}}` is syntax-only checker (fast). -{{- end -}} -{{ if .VeryOpinionated -}} - `{{.Name}}` is very opinionated. -{{- end -}} -{{ end -}} +{{ if .Note }} +**Note:** +{{ .Note }} +{{- end }} +{{- end }}