"Fossies" - the Fresh Open Source Software Archive

Member "buildah-1.27.2/tests/tools/vendor/github.com/mgechev/revive/rule/add-constant.go" (20 Sep 2022, 3713 Bytes) of package /linux/misc/buildah-1.27.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "add-constant.go": 1.26.4_vs_1.27.0.

    1 package rule
    2 
    3 import (
    4     "fmt"
    5     "go/ast"
    6     "strconv"
    7     "strings"
    8 
    9     "github.com/mgechev/revive/lint"
   10 )
   11 
   12 const (
   13     defaultStrLitLimit = 2
   14     kindFLOAT          = "FLOAT"
   15     kindINT            = "INT"
   16     kindSTRING         = "STRING"
   17 )
   18 
   19 type whiteList map[string]map[string]bool
   20 
   21 func newWhiteList() whiteList {
   22     return map[string]map[string]bool{kindINT: {}, kindFLOAT: {}, kindSTRING: {}}
   23 }
   24 
   25 func (wl whiteList) add(kind, list string) {
   26     elems := strings.Split(list, ",")
   27     for _, e := range elems {
   28         wl[kind][e] = true
   29     }
   30 }
   31 
   32 // AddConstantRule lints unused params in functions.
   33 type AddConstantRule struct {
   34     whiteList   whiteList
   35     strLitLimit int
   36 }
   37 
   38 // Apply applies the rule to given file.
   39 func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
   40     if r.whiteList == nil {
   41         r.strLitLimit = defaultStrLitLimit
   42         r.whiteList = newWhiteList()
   43         if len(arguments) > 0 {
   44             args, ok := arguments[0].(map[string]interface{})
   45             if !ok {
   46                 panic(fmt.Sprintf("Invalid argument to the add-constant rule. Expecting a k,v map, got %T", arguments[0]))
   47             }
   48             for k, v := range args {
   49                 kind := ""
   50                 switch k {
   51                 case "allowFloats":
   52                     kind = kindFLOAT
   53                     fallthrough
   54                 case "allowInts":
   55                     if kind == "" {
   56                         kind = kindINT
   57                     }
   58                     fallthrough
   59                 case "allowStrs":
   60                     if kind == "" {
   61                         kind = kindSTRING
   62                     }
   63                     list, ok := v.(string)
   64                     if !ok {
   65                         panic(fmt.Sprintf("Invalid argument to the add-constant rule, string expected. Got '%v' (%T)", v, v))
   66                     }
   67                     r.whiteList.add(kind, list)
   68                 case "maxLitCount":
   69                     sl, ok := v.(string)
   70                     if !ok {
   71                         panic(fmt.Sprintf("Invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v' (%T)", v, v))
   72                     }
   73 
   74                     limit, err := strconv.Atoi(sl)
   75                     if err != nil {
   76                         panic(fmt.Sprintf("Invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v))
   77                     }
   78                     r.strLitLimit = limit
   79                 }
   80             }
   81         }
   82     }
   83 
   84     var failures []lint.Failure
   85 
   86     onFailure := func(failure lint.Failure) {
   87         failures = append(failures, failure)
   88     }
   89 
   90     w := lintAddConstantRule{onFailure: onFailure, strLits: make(map[string]int), strLitLimit: r.strLitLimit, whiteLst: r.whiteList}
   91 
   92     ast.Walk(w, file.AST)
   93 
   94     return failures
   95 }
   96 
   97 // Name returns the rule name.
   98 func (r *AddConstantRule) Name() string {
   99     return "add-constant"
  100 }
  101 
  102 type lintAddConstantRule struct {
  103     onFailure   func(lint.Failure)
  104     strLits     map[string]int
  105     strLitLimit int
  106     whiteLst    whiteList
  107 }
  108 
  109 func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor {
  110     switch n := node.(type) {
  111     case *ast.GenDecl:
  112         return nil // skip declarations
  113     case *ast.BasicLit:
  114         switch kind := n.Kind.String(); kind {
  115         case kindFLOAT, kindINT:
  116             w.checkNumLit(kind, n)
  117         case kindSTRING:
  118             w.checkStrLit(n)
  119         }
  120     }
  121 
  122     return w
  123 }
  124 
  125 func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
  126     if w.whiteLst[kindSTRING][n.Value] {
  127         return
  128     }
  129 
  130     count := w.strLits[n.Value]
  131     if count >= 0 {
  132         w.strLits[n.Value] = count + 1
  133         if w.strLits[n.Value] > w.strLitLimit {
  134             w.onFailure(lint.Failure{
  135                 Confidence: 1,
  136                 Node:       n,
  137                 Category:   "style",
  138                 Failure:    fmt.Sprintf("string literal %s appears, at least, %d times, create a named constant for it", n.Value, w.strLits[n.Value]),
  139             })
  140             w.strLits[n.Value] = -1 // mark it to avoid failing again on the same literal
  141         }
  142     }
  143 }
  144 
  145 func (w lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) {
  146     if w.whiteLst[kind][n.Value] {
  147         return
  148     }
  149 
  150     w.onFailure(lint.Failure{
  151         Confidence: 1,
  152         Node:       n,
  153         Category:   "style",
  154         Failure:    fmt.Sprintf("avoid magic numbers like '%s', create a named constant for it", n.Value),
  155     })
  156 }