mirror of
https://github.com/mgechev/revive.git
synced 2025-01-10 03:17:11 +02:00
79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
|
package rule
|
||
|
|
||
|
import (
|
||
|
"go/ast"
|
||
|
|
||
|
"github.com/mgechev/revive/lint"
|
||
|
)
|
||
|
|
||
|
// EarlyReturnRule lints given else constructs.
|
||
|
type EarlyReturnRule struct{}
|
||
|
|
||
|
// Apply applies the rule to given file.
|
||
|
func (r *EarlyReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||
|
var failures []lint.Failure
|
||
|
|
||
|
onFailure := func(failure lint.Failure) {
|
||
|
failures = append(failures, failure)
|
||
|
}
|
||
|
|
||
|
w := lintEarlyReturnRule{onFailure: onFailure}
|
||
|
ast.Walk(w, file.AST)
|
||
|
return failures
|
||
|
}
|
||
|
|
||
|
// Name returns the rule name.
|
||
|
func (r *EarlyReturnRule) Name() string {
|
||
|
return "early-return"
|
||
|
}
|
||
|
|
||
|
type lintEarlyReturnRule struct {
|
||
|
onFailure func(lint.Failure)
|
||
|
}
|
||
|
|
||
|
func (w lintEarlyReturnRule) Visit(node ast.Node) ast.Visitor {
|
||
|
switch n := node.(type) {
|
||
|
case *ast.IfStmt:
|
||
|
if n.Else == nil {
|
||
|
// no else branch
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
elseBlock, ok := n.Else.(*ast.BlockStmt)
|
||
|
if !ok {
|
||
|
// is if-else-if
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
lenElseBlock := len(elseBlock.List)
|
||
|
if lenElseBlock < 1 {
|
||
|
// empty else block, continue (there is another rule that warns on empty blocks)
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
lenThenBlock := len(n.Body.List)
|
||
|
if lenThenBlock < 1 {
|
||
|
// then block is empty thus the stmt can be simplified
|
||
|
w.onFailure(lint.Failure{
|
||
|
Confidence: 1,
|
||
|
Node: n,
|
||
|
Failure: "if c { } else {... return} can be simplified to if !c { ... return }",
|
||
|
})
|
||
|
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
_, lastThenStmtIsReturn := n.Body.List[lenThenBlock-1].(*ast.ReturnStmt)
|
||
|
_, lastElseStmtIsReturn := elseBlock.List[lenElseBlock-1].(*ast.ReturnStmt)
|
||
|
if lastElseStmtIsReturn && !lastThenStmtIsReturn {
|
||
|
w.onFailure(lint.Failure{
|
||
|
Confidence: 1,
|
||
|
Node: n,
|
||
|
Failure: "if c {...} else {... return } can be simplified to if !c { ... return } ...",
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return w
|
||
|
}
|