|
- package rule
-
- import (
- "go/ast"
- "go/token"
-
- "github.com/mgechev/revive/lint"
- )
-
- // UnnecessaryStmtRule warns on unnecessary statements.
- type UnnecessaryStmtRule struct{}
-
- // Apply applies the rule to given file.
- func (r *UnnecessaryStmtRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
- var failures []lint.Failure
- onFailure := func(failure lint.Failure) {
- failures = append(failures, failure)
- }
-
- w := lintUnnecessaryStmtRule{onFailure}
- ast.Walk(w, file.AST)
- return failures
- }
-
- // Name returns the rule name.
- func (r *UnnecessaryStmtRule) Name() string {
- return "unnecessary-stmt"
- }
-
- type lintUnnecessaryStmtRule struct {
- onFailure func(lint.Failure)
- }
-
- func (w lintUnnecessaryStmtRule) Visit(node ast.Node) ast.Visitor {
- switch n := node.(type) {
- case *ast.FuncDecl:
- if n.Body == nil || n.Type.Results != nil {
- return w
- }
- stmts := n.Body.List
- if len(stmts) == 0 {
- return w
- }
-
- lastStmt := stmts[len(stmts)-1]
- rs, ok := lastStmt.(*ast.ReturnStmt)
- if !ok {
- return w
- }
-
- if len(rs.Results) == 0 {
- w.newFailure(lastStmt, "omit unnecessary return statement")
- }
-
- case *ast.SwitchStmt:
- w.checkSwitchBody(n.Body)
- case *ast.TypeSwitchStmt:
- w.checkSwitchBody(n.Body)
- case *ast.CaseClause:
- if n.Body == nil {
- return w
- }
- stmts := n.Body
- if len(stmts) == 0 {
- return w
- }
-
- lastStmt := stmts[len(stmts)-1]
- rs, ok := lastStmt.(*ast.BranchStmt)
- if !ok {
- return w
- }
-
- if rs.Tok == token.BREAK && rs.Label == nil {
- w.newFailure(lastStmt, "omit unnecessary break at the end of case clause")
- }
- }
-
- return w
- }
-
- func (w lintUnnecessaryStmtRule) checkSwitchBody(b *ast.BlockStmt) {
- cases := b.List
- if len(cases) != 1 {
- return
- }
-
- cc, ok := cases[0].(*ast.CaseClause)
- if !ok {
- return
- }
-
- if len(cc.List) > 1 { // skip cases with multiple expressions
- return
- }
-
- w.newFailure(b, "switch with only one case can be replaced by an if-then")
- }
-
- func (w lintUnnecessaryStmtRule) newFailure(node ast.Node, msg string) {
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: node,
- Category: "style",
- Failure: msg,
- })
- }
|