71 lines
1.6 KiB
Go
71 lines
1.6 KiB
Go
package checkers
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
|
|
"github.com/go-lintpack/lintpack"
|
|
"github.com/go-lintpack/lintpack/astwalk"
|
|
)
|
|
|
|
func init() {
|
|
var info lintpack.CheckerInfo
|
|
info.Name = "emptyFallthrough"
|
|
info.Tags = []string{"style", "experimental"}
|
|
info.Summary = "Detects fallthrough that can be avoided by using multi case values"
|
|
info.Before = `switch kind {
|
|
case reflect.Int:
|
|
fallthrough
|
|
case reflect.Int32:
|
|
return Int
|
|
}`
|
|
info.After = `switch kind {
|
|
case reflect.Int, reflect.Int32:
|
|
return Int
|
|
}`
|
|
|
|
collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker {
|
|
return astwalk.WalkerForStmt(&emptyFallthroughChecker{ctx: ctx})
|
|
})
|
|
}
|
|
|
|
type emptyFallthroughChecker struct {
|
|
astwalk.WalkHandler
|
|
ctx *lintpack.CheckerContext
|
|
}
|
|
|
|
func (c *emptyFallthroughChecker) VisitStmt(stmt ast.Stmt) {
|
|
ss, ok := stmt.(*ast.SwitchStmt)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
prevCaseDefault := false
|
|
for i := len(ss.Body.List) - 1; i >= 0; i-- {
|
|
if cc, ok := ss.Body.List[i].(*ast.CaseClause); ok {
|
|
warn := false
|
|
if len(cc.Body) == 1 {
|
|
if bs, ok := cc.Body[0].(*ast.BranchStmt); ok && bs.Tok == token.FALLTHROUGH {
|
|
warn = true
|
|
if prevCaseDefault {
|
|
c.warnDefault(bs)
|
|
} else {
|
|
c.warn(bs)
|
|
}
|
|
}
|
|
}
|
|
if !warn {
|
|
prevCaseDefault = cc.List == nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *emptyFallthroughChecker) warnDefault(cause ast.Node) {
|
|
c.ctx.Warn(cause, "remove empty case containing only fallthrough to default case")
|
|
}
|
|
|
|
func (c *emptyFallthroughChecker) warn(cause ast.Node) {
|
|
c.ctx.Warn(cause, "replace empty case containing only fallthrough with expression list")
|
|
}
|