108 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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,
 | |
| 	})
 | |
| }
 |