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:
commit
85f716873b
17
README.md
17
README.md
@ -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.
|
||||
|
@ -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
7
fixtures/var-naming.go
Normal file
@ -0,0 +1,7 @@
|
||||
package fixtures
|
||||
|
||||
func foo() string {
|
||||
customId := "result"
|
||||
customVm := "result" // MATCH /var customVm should be customVM/
|
||||
return customId
|
||||
}
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
14
test/var-naming_test.go
Normal 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"}},
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user