github.com/songshiyun/revive@v1.1.5-0.20220323112655-f8433a19b3c5/rule/banned-characters.go (about)

     1  package rule
     2  
     3  import (
     4  	"fmt"
     5  	"go/ast"
     6  	"strings"
     7  
     8  	"github.com/songshiyun/revive/lint"
     9  )
    10  
    11  // BannedCharsRule checks if a file contains banned characters.
    12  type BannedCharsRule struct {
    13  	bannedCharList []string
    14  }
    15  
    16  const bannedCharsRuleName = "banned-characters"
    17  
    18  // Apply applied the rule to the given file.
    19  func (r *BannedCharsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
    20  	if r.bannedCharList == nil {
    21  		checkNumberOfArguments(1, arguments, bannedCharsRuleName)
    22  		r.bannedCharList = r.getBannedCharsList(arguments)
    23  	}
    24  
    25  	var failures []lint.Failure
    26  	onFailure := func(failure lint.Failure) {
    27  		failures = append(failures, failure)
    28  	}
    29  
    30  	w := lintBannedCharsRule{
    31  		bannedChars: r.bannedCharList,
    32  		onFailure:   onFailure,
    33  	}
    34  	ast.Walk(w, file.AST)
    35  	return failures
    36  }
    37  
    38  // Name returns the rule name
    39  func (r *BannedCharsRule) Name() string {
    40  	return bannedCharsRuleName
    41  }
    42  
    43  // getBannedCharsList converts arguments into the banned characters list
    44  func (r *BannedCharsRule) getBannedCharsList(args lint.Arguments) []string {
    45  	var bannedChars []string
    46  	for _, char := range args {
    47  		charStr, ok := char.(string)
    48  		if !ok {
    49  			panic(fmt.Sprintf("Invalid argument for the %s rule: expecting a string, got %T", r.Name(), char))
    50  		}
    51  		bannedChars = append(bannedChars, charStr)
    52  	}
    53  
    54  	return bannedChars
    55  }
    56  
    57  type lintBannedCharsRule struct {
    58  	bannedChars []string
    59  	onFailure   func(lint.Failure)
    60  }
    61  
    62  // Visit checks for each node if an identifier contains banned characters
    63  func (w lintBannedCharsRule) Visit(node ast.Node) ast.Visitor {
    64  	n, ok := node.(*ast.Ident)
    65  	if !ok {
    66  		return w
    67  	}
    68  	for _, c := range w.bannedChars {
    69  		ok := strings.Contains(n.Name, c)
    70  		if ok {
    71  			w.onFailure(lint.Failure{
    72  				Confidence: 1,
    73  				Failure:    fmt.Sprintf("banned character found: %s", c),
    74  				RuleName:   bannedCharsRuleName,
    75  				Node:       n,
    76  			})
    77  		}
    78  	}
    79  
    80  	return w
    81  }