...
1
16
17 package warn
18
19 import (
20 "fmt"
21 "strings"
22
23 "github.com/bazelbuild/buildtools/build"
24 "github.com/bazelbuild/buildtools/bzlenv"
25 )
26
27 var ambiguousNames = map[string]bool{
28 "I": true,
29 "l": true,
30 "O": true,
31 }
32
33
34 func ambiguousNameCheck(expr build.Expr, name string, findings []*LinterFinding) []*LinterFinding {
35 if ambiguousNames[name] {
36 findings = append(findings,
37 makeLinterFinding(expr, `Never use 'l', 'I', or 'O' as names (they're too easily confused with 'I', 'l', or '0').`))
38 }
39 return findings
40 }
41
42 func confusingNameWarning(f *build.File) []*LinterFinding {
43 var findings []*LinterFinding
44
45 for _, ident := range collectLocalVariables(f.Stmt) {
46 findings = ambiguousNameCheck(ident, ident.Name, findings)
47 }
48
49 build.Walk(f, func(expr build.Expr, stack []build.Expr) {
50 switch expr := expr.(type) {
51 case *build.DefStmt:
52 findings = ambiguousNameCheck(expr, expr.Name, findings)
53 for _, param := range expr.Params {
54 name, _ := build.GetParamName(param)
55 findings = ambiguousNameCheck(param, name, findings)
56 }
57 for _, ident := range collectLocalVariables(expr.Body) {
58 findings = ambiguousNameCheck(ident, ident.Name, findings)
59 }
60 case *build.Comprehension:
61 for _, clause := range expr.Clauses {
62 forClause, ok := clause.(*build.ForClause)
63 if !ok {
64 continue
65 }
66 for _, ident := range bzlenv.CollectLValues(forClause.Vars) {
67 findings = ambiguousNameCheck(ident, ident.Name, findings)
68 }
69 }
70 }
71 })
72
73 return findings
74 }
75
76 func isUpperCamelCase(name string) bool {
77 if strings.HasPrefix(name, "_") {
78
79 name = name[1:]
80 }
81 return !strings.ContainsRune(name, '_') && name == strings.Title(name)
82 }
83
84 func isLowerSnakeCase(name string) bool {
85 return name == strings.ToLower(name)
86 }
87
88 func isUpperSnakeCase(name string) bool {
89 return name == strings.ToUpper(name)
90 }
91
92 func nameConventionsWarning(f *build.File) []*LinterFinding {
93 var findings []*LinterFinding
94
95 build.WalkStatements(f, func(stmt build.Expr, stack []build.Expr) (err error) {
96
97
98 binary, ok := stmt.(*build.AssignExpr)
99 if !ok {
100 return
101 }
102 for _, ident := range bzlenv.CollectLValues(binary.LHS) {
103 if isLowerSnakeCase(ident.Name) || isUpperSnakeCase(ident.Name) {
104 continue
105 }
106 if isUpperCamelCase(ident.Name) && strings.HasSuffix(ident.Name, "Info") {
107 continue
108 }
109 findings = append(findings,
110 makeLinterFinding(ident,
111 fmt.Sprintf(`Variable name "%s" should be lower_snake_case (for variables), UPPER_SNAKE_CASE (for constants), or UpperCamelCase ending with 'Info' (for providers).`, ident.Name)))
112 }
113 return
114 })
115
116 return findings
117 }
118
View as plain text