72 lines
1.5 KiB
Go
72 lines
1.5 KiB
Go
package checkers
|
|
|
|
import (
|
|
"go/ast"
|
|
|
|
"github.com/go-lintpack/lintpack"
|
|
"github.com/go-lintpack/lintpack/astwalk"
|
|
"github.com/go-toolsmith/astp"
|
|
)
|
|
|
|
func init() {
|
|
var info lintpack.CheckerInfo
|
|
info.Name = "elseif"
|
|
info.Tags = []string{"style"}
|
|
info.Params = lintpack.CheckerParams{
|
|
"skipBalanced": {
|
|
Value: true,
|
|
Usage: "whether to skip balanced if-else pairs",
|
|
},
|
|
}
|
|
info.Summary = "Detects else with nested if statement that can be replaced with else-if"
|
|
info.Before = `
|
|
if cond1 {
|
|
} else {
|
|
if x := cond2; x {
|
|
}
|
|
}`
|
|
info.After = `
|
|
if cond1 {
|
|
} else if x := cond2; x {
|
|
}`
|
|
|
|
collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker {
|
|
c := &elseifChecker{ctx: ctx}
|
|
c.skipBalanced = info.Params.Bool("skipBalanced")
|
|
return astwalk.WalkerForStmt(c)
|
|
})
|
|
}
|
|
|
|
type elseifChecker struct {
|
|
astwalk.WalkHandler
|
|
ctx *lintpack.CheckerContext
|
|
|
|
skipBalanced bool
|
|
}
|
|
|
|
func (c *elseifChecker) VisitStmt(stmt ast.Stmt) {
|
|
if stmt, ok := stmt.(*ast.IfStmt); ok {
|
|
elseBody, ok := stmt.Else.(*ast.BlockStmt)
|
|
if !ok || len(elseBody.List) != 1 {
|
|
return
|
|
}
|
|
innerIfStmt, ok := elseBody.List[0].(*ast.IfStmt)
|
|
if !ok {
|
|
return
|
|
}
|
|
balanced := len(stmt.Body.List) == 1 &&
|
|
astp.IsIfStmt(stmt.Body.List[0])
|
|
if balanced && c.skipBalanced {
|
|
return // Configured to skip balanced statements
|
|
}
|
|
if innerIfStmt.Else != nil {
|
|
return
|
|
}
|
|
c.warn(stmt.Else)
|
|
}
|
|
}
|
|
|
|
func (c *elseifChecker) warn(cause ast.Node) {
|
|
c.ctx.Warn(cause, "can replace 'else {if cond {}}' with 'else if cond {}'")
|
|
}
|