1
0
mirror of https://github.com/mgechev/revive.git synced 2024-11-28 08:49:11 +02:00

Merge pull request #61 from mgechev/minko/custom-inits

Add white & black lists for var-naming
This commit is contained in:
SalvadorC 2018-09-17 12:47:21 +02:00 committed by GitHub
commit 85f716873b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 50 deletions

View File

@ -243,7 +243,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
| `exported` | n/a | Naming and commenting conventions on exported symbols. | yes | no |
| `if-return` | n/a | Redundant if when returning an error. | yes | no |
| `increment-decrement` | n/a | Use `i++` and `i--` instead of `i += 1` and `i -= 1`. | yes | no |
| `var-naming` | n/a | Naming rules. | yes | no |
| `var-naming` | whitelist & blacklist of initialisms | Naming rules. | yes | no |
| `package-comments` | n/a | Package commenting conventions. | yes | no |
| `range` | n/a | Prevents redundant variables when iterating over a collection. | yes | no |
| `receiver-naming` | n/a | Conventions around the naming of receivers. | yes | no |
@ -270,6 +270,21 @@ List of all available rules. The rules ported from `golint` are left unchanged a
| `bool-literal-in-expr`| n/a | Suggests removing Boolean literals from logic expressions | no | no |
| `redefines-builtin-id`| n/a | Warns on redefinitions of builtin identifiers | no | no |
## Configurable rules
Here you can find how you can configure some of the existing rules:
### `var-naming`
This rule accepts two slices of strings, a whitelist and a blacklist of initialisms. By default the rule behaves exactly as the alternative in `golint` but optionally, you can relax it (see [golint/lint/issues/89](https://github.com/golang/lint/issues/89))
```toml
[rule.var-naming]
arguments = [["ID"], ["VM"]]
```
This way, revive will not warn for identifier called `customId` but will warn that `customVm` should be called `customVM`.
## Available Formatters
This section lists all the available formatters and provides a screenshot for each one.

View File

@ -22,4 +22,4 @@ warningCode = 0
[rule.time-naming]
[rule.unexported-return]
[rule.indent-error-flow]
[rule.errorf]
[rule.errorf]

7
fixtures/var-naming.go Normal file
View File

@ -0,0 +1,7 @@
package fixtures
func foo() string {
customId := "result"
customVm := "result" // MATCH /var customVm should be customVM/
return customId
}

View File

@ -6,7 +6,7 @@ import (
)
// Name returns a different name if it should be different.
func Name(name string) (should string) {
func Name(name string, whitelist, blacklist []string) (should string) {
// Fast path for simple cases: "_" and all lowercase.
if name == "_" {
return name
@ -56,7 +56,17 @@ func Name(name string) (should string) {
// [w,i) is a word.
word := string(runes[w:i])
if u := strings.ToUpper(word); commonInitialisms[u] {
ignoreInitWarnings := map[string]bool{}
for _, i := range whitelist {
ignoreInitWarnings[i] = true
}
extraInits := map[string]bool{}
for _, i := range blacklist {
extraInits[i] = true
}
if u := strings.ToUpper(word); (commonInitialisms[u] || extraInits[u]) && !ignoreInitWarnings[u] {
// Keep consistent case, which is lowercase only at the start.
if w == 0 && unicode.IsLower(runes[w]) {
u = strings.ToLower(u)

View File

@ -1,9 +1,10 @@
package rule
import (
"github.com/mgechev/revive/lint"
"go/ast"
"go/token"
"github.com/mgechev/revive/lint"
)
// BoolLiteralRule warns when logic expressions contains Boolean literals.

View File

@ -61,47 +61,6 @@ func isCgoExported(f *ast.FuncDecl) bool {
return false
}
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
var allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`)
func isIdent(expr ast.Expr, ident string) bool {

View File

@ -16,10 +16,23 @@ type VarNamingRule struct{}
func (r *VarNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
var failures []lint.Failure
var whitelist []string
var blacklist []string
if len(arguments) >= 1 {
whitelist = getList(arguments[0], "whitelist")
}
if len(arguments) >= 2 {
blacklist = getList(arguments[1], "blacklist")
}
fileAst := file.AST
walker := lintNames{
file: file,
fileAst: fileAst,
file: file,
fileAst: fileAst,
whitelist: whitelist,
blacklist: blacklist,
onFailure: func(failure lint.Failure) {
failures = append(failures, failure)
},
@ -87,7 +100,7 @@ func check(id *ast.Ident, thing string, w *lintNames) {
})
}
should := lint.Name(id.Name)
should := lint.Name(id.Name, w.whitelist, w.blacklist)
if id.Name == should {
return
}
@ -117,6 +130,8 @@ type lintNames struct {
lastGen *ast.GenDecl
genDeclMissingComments map[*ast.GenDecl]bool
onFailure func(lint.Failure)
whitelist []string
blacklist []string
}
func (w *lintNames) Visit(n ast.Node) ast.Visitor {
@ -202,3 +217,19 @@ func (w *lintNames) Visit(n ast.Node) ast.Visitor {
}
return w
}
func getList(arg interface{}, argName string) []string {
temp, ok := arg.([]interface{})
if !ok {
panic(fmt.Sprintf("Invalid argument to the var-naming rule. Expecting a %s of type slice with initialisms, got %T", argName, arg))
}
var list []string
for _, v := range temp {
if val, ok := v.(string); ok {
list = append(list, val)
} else {
panic(fmt.Sprintf("Invalid %s values of the var-naming rule. Expecting slice of strings but got element of type %T", val, arg))
}
}
return list
}

View File

@ -275,7 +275,7 @@ func TestLintName(t *testing.T) {
{"IEEE802_16Bit", "IEEE802_16Bit"},
}
for _, test := range tests {
got := lint.Name(test.name)
got := lint.Name(test.name, nil, nil)
if got != test.want {
t.Errorf("lintName(%q) = %q, want %q", test.name, got, test.want)
}

14
test/var-naming_test.go Normal file
View File

@ -0,0 +1,14 @@
package test
import (
"testing"
"github.com/mgechev/revive/lint"
"github.com/mgechev/revive/rule"
)
func TestVarNaming(t *testing.T) {
testRule(t, "var-naming", &rule.VarNamingRule{}, &lint.RuleConfig{
Arguments: []interface{}{[]interface{}{"ID"}, []interface{}{"VM"}},
})
}