@@ -8,72 +8,73 @@ import (
8
8
"github.com/mgechev/revive/lint"
9
9
)
10
10
11
+ var builtInConstAndVars = map [string ]bool {
12
+ "true" : true ,
13
+ "false" : true ,
14
+ "iota" : true ,
15
+ "nil" : true ,
16
+ }
17
+
18
+ var builtFunctions = map [string ]bool {
19
+ "append" : true ,
20
+ "cap" : true ,
21
+ "close" : true ,
22
+ "complex" : true ,
23
+ "copy" : true ,
24
+ "delete" : true ,
25
+ "imag" : true ,
26
+ "len" : true ,
27
+ "make" : true ,
28
+ "new" : true ,
29
+ "panic" : true ,
30
+ "print" : true ,
31
+ "println" : true ,
32
+ "real" : true ,
33
+ "recover" : true ,
34
+ }
35
+
36
+ var builtInTypes = map [string ]bool {
37
+ "ComplexType" : true ,
38
+ "FloatType" : true ,
39
+ "IntegerType" : true ,
40
+ "Type" : true ,
41
+ "Type1" : true ,
42
+ "bool" : true ,
43
+ "byte" : true ,
44
+ "complex128" : true ,
45
+ "complex64" : true ,
46
+ "error" : true ,
47
+ "float32" : true ,
48
+ "float64" : true ,
49
+ "int" : true ,
50
+ "int16" : true ,
51
+ "int32" : true ,
52
+ "int64" : true ,
53
+ "int8" : true ,
54
+ "rune" : true ,
55
+ "string" : true ,
56
+ "uint" : true ,
57
+ "uint16" : true ,
58
+ "uint32" : true ,
59
+ "uint64" : true ,
60
+ "uint8" : true ,
61
+ "uintptr" : true ,
62
+ "any" : true ,
63
+ }
64
+
11
65
// RedefinesBuiltinIDRule warns when a builtin identifier is shadowed.
12
66
type RedefinesBuiltinIDRule struct {}
13
67
14
68
// Apply applies the rule to given file.
15
69
func (r * RedefinesBuiltinIDRule ) Apply (file * lint.File , _ lint.Arguments ) []lint.Failure {
16
70
var failures []lint.Failure
17
71
18
- builtInConstAndVars := map [string ]bool {
19
- "true" : true ,
20
- "false" : true ,
21
- "iota" : true ,
22
- "nil" : true ,
23
- }
24
-
25
- builtFunctions := map [string ]bool {
26
- "append" : true ,
27
- "cap" : true ,
28
- "close" : true ,
29
- "complex" : true ,
30
- "copy" : true ,
31
- "delete" : true ,
32
- "imag" : true ,
33
- "len" : true ,
34
- "make" : true ,
35
- "new" : true ,
36
- "panic" : true ,
37
- "print" : true ,
38
- "println" : true ,
39
- "real" : true ,
40
- "recover" : true ,
41
- }
42
-
43
- builtInTypes := map [string ]bool {
44
- "ComplexType" : true ,
45
- "FloatType" : true ,
46
- "IntegerType" : true ,
47
- "Type" : true ,
48
- "Type1" : true ,
49
- "bool" : true ,
50
- "byte" : true ,
51
- "complex128" : true ,
52
- "complex64" : true ,
53
- "error" : true ,
54
- "float32" : true ,
55
- "float64" : true ,
56
- "int" : true ,
57
- "int16" : true ,
58
- "int32" : true ,
59
- "int64" : true ,
60
- "int8" : true ,
61
- "rune" : true ,
62
- "string" : true ,
63
- "uint" : true ,
64
- "uint16" : true ,
65
- "uint32" : true ,
66
- "uint64" : true ,
67
- "uint8" : true ,
68
- "uintptr" : true ,
69
- }
70
-
71
72
onFailure := func (failure lint.Failure ) {
72
73
failures = append (failures , failure )
73
74
}
74
75
75
76
astFile := file .AST
76
- w := & lintRedefinesBuiltinID {builtInConstAndVars , builtFunctions , builtInTypes , onFailure }
77
+ w := & lintRedefinesBuiltinID {onFailure }
77
78
ast .Walk (w , astFile )
78
79
79
80
return failures
@@ -85,34 +86,46 @@ func (r *RedefinesBuiltinIDRule) Name() string {
85
86
}
86
87
87
88
type lintRedefinesBuiltinID struct {
88
- constsAndVars map [string ]bool
89
- funcs map [string ]bool
90
- types map [string ]bool
91
- onFailure func (lint.Failure )
89
+ onFailure func (lint.Failure )
92
90
}
93
91
94
92
func (w * lintRedefinesBuiltinID ) Visit (node ast.Node ) ast.Visitor {
95
93
switch n := node .(type ) {
96
94
case * ast.GenDecl :
97
- if n .Tok != token .TYPE {
98
- return nil // skip if not type declaration
99
- }
100
- typeSpec , ok := n .Specs [0 ].(* ast.TypeSpec )
101
- if ! ok {
102
- return nil
103
- }
104
- id := typeSpec .Name .Name
105
- if w .types [id ] {
106
- w .addFailure (n , fmt .Sprintf ("redefinition of the built-in type %s" , id ))
95
+ switch n .Tok {
96
+ case token .TYPE :
97
+ typeSpec , ok := n .Specs [0 ].(* ast.TypeSpec )
98
+ if ! ok {
99
+ return nil
100
+ }
101
+ id := typeSpec .Name .Name
102
+ if ok , bt := w .isBuiltIn (id ); ok {
103
+ w .addFailure (n , fmt .Sprintf ("redefinition of the built-in %s %s" , bt , id ))
104
+ }
105
+ case token .VAR , token .CONST :
106
+ for _ , vs := range n .Specs {
107
+ valSpec , ok := vs .(* ast.ValueSpec )
108
+ if ! ok {
109
+ continue
110
+ }
111
+ for _ , name := range valSpec .Names {
112
+ if ok , bt := w .isBuiltIn (name .Name ); ok {
113
+ w .addFailure (n , fmt .Sprintf ("redefinition of the built-in %s %s" , bt , name ))
114
+ }
115
+ }
116
+ }
117
+ default :
118
+ return nil // skip if not type/var/const declaration
107
119
}
120
+
108
121
case * ast.FuncDecl :
109
122
if n .Recv != nil {
110
123
return w // skip methods
111
124
}
112
125
113
126
id := n .Name .Name
114
- if w . funcs [ id ] {
115
- w .addFailure (n , fmt .Sprintf ("redefinition of the built-in function %s" , id ))
127
+ if ok , bt := w . isBuiltIn ( id ); ok {
128
+ w .addFailure (n , fmt .Sprintf ("redefinition of the built-in %s %s" , bt , id ))
116
129
}
117
130
case * ast.AssignStmt :
118
131
for _ , e := range n .Lhs {
@@ -121,13 +134,20 @@ func (w *lintRedefinesBuiltinID) Visit(node ast.Node) ast.Visitor {
121
134
continue
122
135
}
123
136
124
- if w . constsAndVars [ id .Name ] {
137
+ if ok , bt := w . isBuiltIn ( id .Name ); ok {
125
138
var msg string
126
- if n .Tok == token .DEFINE {
127
- msg = fmt .Sprintf ("assignment creates a shadow of built-in identifier %s" , id .Name )
128
- } else {
129
- msg = fmt .Sprintf ("assignment modifies built-in identifier %s" , id .Name )
139
+ println (bt , id .Name )
140
+ switch bt {
141
+ case "constant or variable" :
142
+ if n .Tok == token .DEFINE {
143
+ msg = fmt .Sprintf ("assignment creates a shadow of built-in identifier %s" , id .Name )
144
+ } else {
145
+ msg = fmt .Sprintf ("assignment modifies built-in identifier %s" , id .Name )
146
+ }
147
+ default :
148
+ msg = fmt .Sprintf ("redefinition of the built-in %s %s" , bt , id )
130
149
}
150
+
131
151
w .addFailure (n , msg )
132
152
}
133
153
}
@@ -144,3 +164,19 @@ func (w lintRedefinesBuiltinID) addFailure(node ast.Node, msg string) {
144
164
Failure : msg ,
145
165
})
146
166
}
167
+
168
+ func (w lintRedefinesBuiltinID ) isBuiltIn (id string ) (r bool , builtInKind string ) {
169
+ if builtFunctions [id ] {
170
+ return true , "function"
171
+ }
172
+
173
+ if builtInConstAndVars [id ] {
174
+ return true , "constant or variable"
175
+ }
176
+
177
+ if builtInTypes [id ] {
178
+ return true , "type"
179
+ }
180
+
181
+ return false , ""
182
+ }
0 commit comments