github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/rule/empty-block.go (about)

     1  package rule
     2  
     3  import (
     4  	"go/ast"
     5  
     6  	"github.com/mgechev/revive/lint"
     7  )
     8  
     9  // EmptyBlockRule lints given else constructs.
    10  type EmptyBlockRule struct{}
    11  
    12  // Apply applies the rule to given file.
    13  func (r *EmptyBlockRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
    14  	var failures []lint.Failure
    15  
    16  	onFailure := func(failure lint.Failure) {
    17  		failures = append(failures, failure)
    18  	}
    19  
    20  	w := lintEmptyBlock{make(map[*ast.BlockStmt]bool, 0), onFailure}
    21  	ast.Walk(w, file.AST)
    22  	return failures
    23  }
    24  
    25  // Name returns the rule name.
    26  func (r *EmptyBlockRule) Name() string {
    27  	return "empty-block"
    28  }
    29  
    30  type lintEmptyBlock struct {
    31  	ignore    map[*ast.BlockStmt]bool
    32  	onFailure func(lint.Failure)
    33  }
    34  
    35  func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
    36  	switch n := node.(type) {
    37  	case *ast.FuncDecl:
    38  		w.ignore[n.Body] = true
    39  		return w
    40  	case *ast.FuncLit:
    41  		w.ignore[n.Body] = true
    42  		return w
    43  	case *ast.RangeStmt:
    44  		if len(n.Body.List) == 0 {
    45  			w.onFailure(lint.Failure{
    46  				Confidence: 0.9,
    47  				Node:       n,
    48  				Category:   "logic",
    49  				Failure:    "this block is empty, you can remove it",
    50  			})
    51  			return nil // skip visiting the range subtree (it will produce a duplicated failure)
    52  		}
    53  	case *ast.BlockStmt:
    54  		if !w.ignore[n] && len(n.List) == 0 {
    55  			w.onFailure(lint.Failure{
    56  				Confidence: 1,
    57  				Node:       n,
    58  				Category:   "logic",
    59  				Failure:    "this block is empty, you can remove it",
    60  			})
    61  		}
    62  	}
    63  
    64  	return w
    65  }