mirror of
https://github.com/mgechev/revive.git
synced 2025-04-27 12:12:10 +02:00
* fix #751 [rule.add-constant] add ignoreFuncs to exclude constants in functions * Update add-constant.go * Update add-constant.go * fix #751 [rule.add-constant] add ignoreFuncs to exclude constants in functions * add details to regex-related errors Co-authored-by: chavacava <salvadorcavadini+github@gmail.com>
This commit is contained in:
parent
5cc9e27ddb
commit
3d83403fb8
@ -85,12 +85,13 @@ _Configuration_:
|
|||||||
* `allowStr`: (string) comma-separated list of allowed string literals
|
* `allowStr`: (string) comma-separated list of allowed string literals
|
||||||
* `allowInts`: (string) comma-separated list of allowed integers
|
* `allowInts`: (string) comma-separated list of allowed integers
|
||||||
* `allowFloats`: (string) comma-separated list of allowed floats
|
* `allowFloats`: (string) comma-separated list of allowed floats
|
||||||
|
* `ignoreFuncs`: (string) comma-separated list of function names regexp patterns to exclude
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[rule.add-constant]
|
[rule.add-constant]
|
||||||
arguments = [{maxLitCount = "3",allowStrs ="\"\"",allowInts="0,1,2",allowFloats="0.0,0.,1.0,1.,2.0,2."}]
|
arguments = [{maxLitCount = "3",allowStrs ="\"\"",allowInts="0,1,2",allowFloats="0.0,0.,1.0,1.,2.0,2.","ignoreFuncs": "os.*,fmt.Println,make"}]
|
||||||
```
|
```
|
||||||
|
|
||||||
## argument-limit
|
## argument-limit
|
||||||
|
@ -3,6 +3,7 @@ package rule
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -33,6 +34,7 @@ func (wl whiteList) add(kind, list string) {
|
|||||||
// AddConstantRule lints unused params in functions.
|
// AddConstantRule lints unused params in functions.
|
||||||
type AddConstantRule struct {
|
type AddConstantRule struct {
|
||||||
whiteList whiteList
|
whiteList whiteList
|
||||||
|
ignoreFunctions []*regexp.Regexp
|
||||||
strLitLimit int
|
strLitLimit int
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
@ -47,7 +49,13 @@ func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lin
|
|||||||
failures = append(failures, failure)
|
failures = append(failures, failure)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := lintAddConstantRule{onFailure: onFailure, strLits: make(map[string]int), strLitLimit: r.strLitLimit, whiteLst: r.whiteList}
|
w := lintAddConstantRule{
|
||||||
|
onFailure: onFailure,
|
||||||
|
strLits: make(map[string]int),
|
||||||
|
strLitLimit: r.strLitLimit,
|
||||||
|
whiteLst: r.whiteList,
|
||||||
|
ignoreFunctions: r.ignoreFunctions,
|
||||||
|
}
|
||||||
|
|
||||||
ast.Walk(w, file.AST)
|
ast.Walk(w, file.AST)
|
||||||
|
|
||||||
@ -64,13 +72,54 @@ type lintAddConstantRule struct {
|
|||||||
strLits map[string]int
|
strLits map[string]int
|
||||||
strLitLimit int
|
strLitLimit int
|
||||||
whiteLst whiteList
|
whiteLst whiteList
|
||||||
|
ignoreFunctions []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor {
|
func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor {
|
||||||
switch n := node.(type) {
|
switch n := node.(type) {
|
||||||
|
case *ast.CallExpr:
|
||||||
|
w.checkFunc(n)
|
||||||
|
return nil
|
||||||
case *ast.GenDecl:
|
case *ast.GenDecl:
|
||||||
return nil // skip declarations
|
return nil // skip declarations
|
||||||
case *ast.BasicLit:
|
case *ast.BasicLit:
|
||||||
|
w.checkLit(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w lintAddConstantRule) checkFunc(expr *ast.CallExpr) {
|
||||||
|
fName := w.getFuncName(expr)
|
||||||
|
|
||||||
|
for _, arg := range expr.Args {
|
||||||
|
switch t := arg.(type) {
|
||||||
|
case *ast.CallExpr:
|
||||||
|
w.checkFunc(t)
|
||||||
|
case *ast.BasicLit:
|
||||||
|
if w.isIgnoredFunc(fName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w.checkLit(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w lintAddConstantRule) getFuncName(expr *ast.CallExpr) string {
|
||||||
|
switch f := expr.Fun.(type) {
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
switch prefix := f.X.(type) {
|
||||||
|
case *ast.Ident:
|
||||||
|
return prefix.Name + "." + f.Sel.Name
|
||||||
|
}
|
||||||
|
case *ast.Ident:
|
||||||
|
return f.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w lintAddConstantRule) checkLit(n *ast.BasicLit) {
|
||||||
switch kind := n.Kind.String(); kind {
|
switch kind := n.Kind.String(); kind {
|
||||||
case kindFLOAT, kindINT:
|
case kindFLOAT, kindINT:
|
||||||
w.checkNumLit(kind, n)
|
w.checkNumLit(kind, n)
|
||||||
@ -79,7 +128,14 @@ func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return w
|
func (w lintAddConstantRule) isIgnoredFunc(fName string) bool {
|
||||||
|
for _, pattern := range w.ignoreFunctions {
|
||||||
|
if pattern.MatchString(fName) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
|
func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
|
||||||
@ -158,6 +214,25 @@ func (r *AddConstantRule) configure(arguments lint.Arguments) {
|
|||||||
panic(fmt.Sprintf("Invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v))
|
panic(fmt.Sprintf("Invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v))
|
||||||
}
|
}
|
||||||
r.strLitLimit = limit
|
r.strLitLimit = limit
|
||||||
|
case "ignoreFuncs":
|
||||||
|
excludes, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("Invalid argument to the ignoreFuncs parameter of add-constant rule, string expected. Got '%v' (%T)", v, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, exclude := range strings.Split(excludes, ",") {
|
||||||
|
exclude = strings.Trim(exclude, " ")
|
||||||
|
if exclude == "" {
|
||||||
|
panic("Invalid argument to the ignoreFuncs parameter of add-constant rule, expected regular expression must not be empty.")
|
||||||
|
}
|
||||||
|
|
||||||
|
exp, err := regexp.Compile(exclude)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Invalid argument to the ignoreFuncs parameter of add-constant rule: regexp %q does not compile: %v", exclude, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
r.ignoreFunctions = append(r.ignoreFunctions, exp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ func TestAddConstant(t *testing.T) {
|
|||||||
"allowStrs": "\"\"",
|
"allowStrs": "\"\"",
|
||||||
"allowInts": "0,1,2",
|
"allowInts": "0,1,2",
|
||||||
"allowFloats": "0.0,1.0",
|
"allowFloats": "0.0,1.0",
|
||||||
|
"ignoreFuncs": "os\\.(CreateFile|WriteFile|Chmod|FindProcess),.Println,ignoredFunc",
|
||||||
}}
|
}}
|
||||||
|
|
||||||
testRule(t, "add-constant", &rule.AddConstantRule{}, &lint.RuleConfig{
|
testRule(t, "add-constant", &rule.AddConstantRule{}, &lint.RuleConfig{
|
||||||
|
35
testdata/add-constant.go
vendored
35
testdata/add-constant.go
vendored
@ -1,5 +1,10 @@
|
|||||||
package fixtures
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
func foo(a, b, c, d int) {
|
func foo(a, b, c, d int) {
|
||||||
a = 1.0 // ignore
|
a = 1.0 // ignore
|
||||||
b = "ignore"
|
b = "ignore"
|
||||||
@ -13,4 +18,34 @@ func foo(a, b, c, d int) {
|
|||||||
println("lit")
|
println("lit")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println(0666) // MATCH /avoid magic numbers like '0666', create a named constant for it/
|
||||||
|
os.Chmod("test", 0666) // ignore
|
||||||
|
os.FindProcess(102100) // ignore
|
||||||
|
fmt.Println("test", 12) // ignore
|
||||||
|
fmt.Printf("%d", 100) // MATCH /avoid magic numbers like '100', create a named constant for it/
|
||||||
|
ignoredFunc(1000) // ignore
|
||||||
|
|
||||||
|
println("The result of calling myFunc is: ", ignoredFunc(100)) // ignore
|
||||||
|
println("result is: ", ignoredFunc(notIgnoredFunc(ignoredFunc(100)))) // ignore
|
||||||
|
println("result of calling myFunc is: ", notIgnoredFunc(ignoredFunc(100))) // ignore
|
||||||
|
|
||||||
|
println("result myFunc is: ", notIgnoredFunc(100)) // MATCH /avoid magic numbers like '100', create a named constant for it/
|
||||||
|
println("The result is: ", ignoredFunc(notIgnoredFunc(100))) // MATCH /avoid magic numbers like '100', create a named constant for it/
|
||||||
|
}
|
||||||
|
|
||||||
|
func myPrintln(s string, num int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func not2ignoredFunc(num int) int {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
func ignoredFunc(num int) int {
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
func notIgnoredFunc(num int) int {
|
||||||
|
return num
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user