github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/indent-error-flow.go (about) 1 package rule 2 3 import ( 4 "go/ast" 5 "go/token" 6 7 "github.com/mgechev/revive/lint" 8 ) 9 10 // IndentErrorFlowRule lints given else constructs. 11 type IndentErrorFlowRule struct{} 12 13 // Apply applies the rule to given file. 14 func (r *IndentErrorFlowRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { 15 var failures []lint.Failure 16 17 onFailure := func(failure lint.Failure) { 18 failures = append(failures, failure) 19 } 20 21 w := lintElse{make(map[*ast.IfStmt]bool), onFailure} 22 ast.Walk(w, file.AST) 23 return failures 24 } 25 26 // Name returns the rule name. 27 func (r *IndentErrorFlowRule) Name() string { 28 return "indent-error-flow" 29 } 30 31 type lintElse struct { 32 ignore map[*ast.IfStmt]bool 33 onFailure func(lint.Failure) 34 } 35 36 func (w lintElse) Visit(node ast.Node) ast.Visitor { 37 ifStmt, ok := node.(*ast.IfStmt) 38 if !ok || ifStmt.Else == nil { 39 return w 40 } 41 if w.ignore[ifStmt] { 42 if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok { 43 w.ignore[elseif] = true 44 } 45 return w 46 } 47 if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok { 48 w.ignore[elseif] = true 49 return w 50 } 51 if _, ok := ifStmt.Else.(*ast.BlockStmt); !ok { 52 // only care about elses without conditions 53 return w 54 } 55 if len(ifStmt.Body.List) == 0 { 56 return w 57 } 58 shortDecl := false // does the if statement have a ":=" initialization statement? 59 if ifStmt.Init != nil { 60 if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE { 61 shortDecl = true 62 } 63 } 64 lastStmt := ifStmt.Body.List[len(ifStmt.Body.List)-1] 65 if _, ok := lastStmt.(*ast.ReturnStmt); ok { 66 extra := "" 67 if shortDecl { 68 extra = " (move short variable declaration to its own line if necessary)" 69 } 70 w.onFailure(lint.Failure{ 71 Confidence: 1, 72 Node: ifStmt.Else, 73 Category: "indent", 74 Failure: "if block ends with a return statement, so drop this else and outdent its block" + extra, 75 }) 76 } 77 return w 78 }