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:**
-
-
-
- Name |
- Short description |
-
-
- appendAssign |
- Detects suspicious append result assignments |
-
-
- assignOp |
- Detects assignments that can be simplified by using assignment operators |
-
-
- blankParam :nerd_face: |
- Detects unused params and suggests to name them as `_` (blank) |
-
-
- boolExprSimplify |
- Detects 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 |
-
-
- busySelect |
- Detects default statement inside a select without a sleep that might waste a CPU time |
-
-
- captLocal |
- Detects capitalized names for local variables |
-
-
- caseOrder |
- Detects erroneous case order inside switch statements |
-
-
- commentedOutCode |
- Detects commented-out code inside function bodies |
-
-
- deadCodeAfterLogFatal |
- Detects dead code that follow panic/fatal logging |
-
-
- defaultCaseOrder |
- Detects when default case in switch isn't on 1st or last position |
-
-
- deferInLoop |
- Detects defer in loop and warns that it will not be executed till the end of function's scope |
-
-
- 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 :nerd_face: |
- 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 |
-
-
- emptyFmt |
- Detects usages of formatting functions without formatting arguments |
-
-
- evalOrder |
- Detects potentially unsafe dependencies on evaluation order |
-
-
- flagName |
- Detects flag names with whitespace |
-
-
- floatCompare |
- Detects fragile float variables comparisons |
-
-
- hugeParam |
- Detects params that incur excessive amount of copying |
-
-
- importPackageName |
- Detects when imported package names are unnecessary renamed |
-
-
- importShadow |
- Detects when imported package names shadowed in assignments |
-
-
- indexAlloc |
- Detects strings.Index calls that may cause unwanted allocs |
-
-
- indexOnlyLoop |
- Detects for loops that can benefit from rewrite to range loop |
-
-
- initClause |
- Detects 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 |
-
-
- namedConst |
- Detects literals that can be replaced with defined named const |
-
-
- nestingReduce |
- Finds where nesting level could be reduced |
-
-
- nilValReturn |
- Detects return statements those results evaluate to nil |
-
-
- ptrToRefParam |
- Detects input and output parameters that have a type of pointer to referential type |
-
-
- sloppyLen |
- Detects usage of `len` when result is obvious or doesn't make sense |
-
-
- sqlRowsClose |
- Detects uses of *sql.Rows without call Close method |
-
-
- stdExpr |
- Detects 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 |
-
-
- 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 |
-
-
- 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 }}
-
-
- Name |
- Short description |
-
- {{- range .Rules }}
- {{- if .Experimental }}
-
- {{ .Name }}{{ if .VeryOpinionated }} :nerd_face:{{ end }} |
- {{.Doc.Summary}} |
-
- {{- end }}
- {{- end }}
-
+[{{ 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 }}