9
9
10
10
'use strict' ;
11
11
12
- var Components = require ( '../util/Components' ) ;
12
+ const Components = require ( '../util/Components' ) ;
13
13
14
14
// Descend through all wrapping TypeCastExpressions and return the expression
15
15
// that was cast.
@@ -40,10 +40,10 @@ function isThisExpression(node) {
40
40
function getInitialClassInfo ( ) {
41
41
return {
42
42
// Set of nodes where state fields were defined.
43
- stateFields : [ ] ,
43
+ stateFields : new Set ( ) ,
44
44
45
45
// Set of names of state fields that we've seen used.
46
- usedStateFields : [ ] ,
46
+ usedStateFields : new Set ( ) ,
47
47
48
48
// Names of local variables that may be pointing to this.state. To
49
49
// track this properly, we would need to keep track of all locals,
@@ -69,57 +69,57 @@ module.exports = {
69
69
// not yet encountered any use of this.state which we have chosen not to
70
70
// analyze. If we encounter any such usage (like this.state being spread as
71
71
// JSX attributes), then this is again set to null.
72
- var classInfo = null ;
72
+ let classInfo = null ;
73
73
74
74
// Returns true if the given node is possibly a reference to `this.state`.
75
75
function isStateReference ( node ) {
76
76
node = uncast ( node ) ;
77
77
78
- var isDirectStateReference =
78
+ const isDirectStateReference =
79
79
node . type === 'MemberExpression' &&
80
80
isThisExpression ( node . object ) &&
81
81
node . property . name === 'state' ;
82
82
83
- var isAliasedStateReference =
83
+ const isAliasedStateReference =
84
84
node . type === 'Identifier' &&
85
85
classInfo . aliases &&
86
- classInfo . aliases . indexOf ( node . name ) >= 0 ;
86
+ classInfo . aliases . has ( node . name ) ;
87
87
88
88
return isDirectStateReference || isAliasedStateReference ;
89
89
}
90
90
91
91
// Takes an ObjectExpression node and adds all named Property nodes to the
92
92
// current set of state fields.
93
93
function addStateFields ( node ) {
94
- node . properties . forEach ( function ( prop ) {
94
+ for ( const prop of node . properties ) {
95
95
if ( prop . type === 'Property' && getName ( prop . key ) !== null ) {
96
- classInfo . stateFields . push ( prop ) ;
96
+ classInfo . stateFields . add ( prop ) ;
97
97
}
98
- } ) ;
98
+ }
99
99
}
100
100
101
101
// Adds the name of the given node as a used state field if the node is an
102
102
// Identifier or a Literal. Other node types are ignored.
103
103
function addUsedStateField ( node ) {
104
- var name = getName ( node ) ;
104
+ const name = getName ( node ) ;
105
105
if ( name ) {
106
- classInfo . usedStateFields . push ( name ) ;
106
+ classInfo . usedStateFields . add ( name ) ;
107
107
}
108
108
}
109
109
110
110
// Records used state fields and new aliases for an ObjectPattern which
111
111
// destructures `this.state`.
112
112
function handleStateDestructuring ( node ) {
113
- node . properties . forEach ( function ( prop ) {
113
+ for ( const prop of node . properties ) {
114
114
if ( prop . type === 'Property' ) {
115
115
addUsedStateField ( prop . key ) ;
116
116
} else if (
117
117
prop . type === 'ExperimentalRestProperty' &&
118
118
classInfo . aliases
119
119
) {
120
- classInfo . aliases . push ( getName ( prop . argument ) ) ;
120
+ classInfo . aliases . add ( getName ( prop . argument ) ) ;
121
121
}
122
- } ) ;
122
+ }
123
123
}
124
124
125
125
// Used to record used state fields and new aliases for both
@@ -128,54 +128,54 @@ module.exports = {
128
128
switch ( left . type ) {
129
129
case 'Identifier' :
130
130
if ( isStateReference ( right ) && classInfo . aliases ) {
131
- classInfo . aliases . push ( left . name ) ;
131
+ classInfo . aliases . add ( left . name ) ;
132
132
}
133
133
break ;
134
134
case 'ObjectPattern' :
135
135
if ( isStateReference ( right ) ) {
136
136
handleStateDestructuring ( left ) ;
137
137
} else if ( isThisExpression ( right ) && classInfo . aliases ) {
138
- left . properties . forEach ( function ( prop ) {
138
+ for ( const prop of left . properties ) {
139
139
if ( prop . type === 'Property' && getName ( prop . key ) === 'state' ) {
140
- var name = getName ( prop . value ) ;
140
+ const name = getName ( prop . value ) ;
141
141
if ( name ) {
142
- classInfo . aliases . push ( name ) ;
142
+ classInfo . aliases . add ( name ) ;
143
143
} else if ( prop . value . type === 'ObjectPattern' ) {
144
144
handleStateDestructuring ( prop . value ) ;
145
145
}
146
146
}
147
- } ) ;
147
+ }
148
148
}
149
149
break ;
150
150
default :
151
- // pass
151
+ // pass
152
152
}
153
153
}
154
154
155
155
function reportUnusedFields ( ) {
156
156
// Report all unused state fields.
157
- classInfo . stateFields . forEach ( function ( node ) {
158
- var name = getName ( node . key ) ;
159
- if ( classInfo . usedStateFields . indexOf ( name ) < 0 ) {
160
- context . report ( node , ' Unused state field: \'' + name + '\'' ) ;
157
+ for ( const node of classInfo . stateFields ) {
158
+ const name = getName ( node . key ) ;
159
+ if ( ! classInfo . usedStateFields . has ( name ) ) {
160
+ context . report ( node , ` Unused state field: ' ${ name } '` ) ;
161
161
}
162
- } ) ;
162
+ }
163
163
}
164
164
165
165
return {
166
- ClassDeclaration : function ( node ) {
166
+ ClassDeclaration ( node ) {
167
167
if ( utils . isES6Component ( node ) ) {
168
168
classInfo = getInitialClassInfo ( ) ;
169
169
}
170
170
} ,
171
171
172
- ObjectExpression : function ( node ) {
172
+ ObjectExpression ( node ) {
173
173
if ( utils . isES5Component ( node ) ) {
174
174
classInfo = getInitialClassInfo ( ) ;
175
175
}
176
176
} ,
177
177
178
- 'ObjectExpression:exit' : function ( node ) {
178
+ 'ObjectExpression:exit' ( node ) {
179
179
if ( ! classInfo ) {
180
180
return ;
181
181
}
@@ -186,15 +186,15 @@ module.exports = {
186
186
}
187
187
} ,
188
188
189
- 'ClassDeclaration:exit' : function ( ) {
189
+ 'ClassDeclaration:exit' ( ) {
190
190
if ( ! classInfo ) {
191
191
return ;
192
192
}
193
193
reportUnusedFields ( ) ;
194
194
classInfo = null ;
195
195
} ,
196
196
197
- CallExpression : function ( node ) {
197
+ CallExpression ( node ) {
198
198
if ( ! classInfo ) {
199
199
return ;
200
200
}
@@ -211,7 +211,7 @@ module.exports = {
211
211
}
212
212
} ,
213
213
214
- ClassProperty : function ( node ) {
214
+ ClassProperty ( node ) {
215
215
if ( ! classInfo ) {
216
216
return ;
217
217
}
@@ -227,35 +227,35 @@ module.exports = {
227
227
}
228
228
} ,
229
229
230
- MethodDefinition : function ( ) {
230
+ MethodDefinition ( ) {
231
231
if ( ! classInfo ) {
232
232
return ;
233
233
}
234
234
// Create a new set for this.state aliases local to this method.
235
- classInfo . aliases = [ ] ;
235
+ classInfo . aliases = new Set ( ) ;
236
236
} ,
237
237
238
- 'MethodDefinition:exit' : function ( ) {
238
+ 'MethodDefinition:exit' ( ) {
239
239
if ( ! classInfo ) {
240
240
return ;
241
241
}
242
242
// Forget our set of local aliases.
243
243
classInfo . aliases = null ;
244
244
} ,
245
245
246
- FunctionExpression : function ( node ) {
246
+ FunctionExpression ( node ) {
247
247
if ( ! classInfo ) {
248
248
return ;
249
249
}
250
250
251
- var parent = node . parent ;
251
+ const parent = node . parent ;
252
252
if ( ! utils . isES5Component ( parent . parent ) ) {
253
253
return ;
254
254
}
255
255
256
256
if ( parent . key . name === 'getInitialState' ) {
257
- var body = node . body . body ;
258
- var lastBodyNode = body [ body . length - 1 ] ;
257
+ const body = node . body . body ;
258
+ const lastBodyNode = body [ body . length - 1 ] ;
259
259
260
260
if (
261
261
lastBodyNode . type === 'ReturnStatement' &&
@@ -265,11 +265,11 @@ module.exports = {
265
265
}
266
266
} else {
267
267
// Create a new set for this.state aliases local to this method.
268
- classInfo . aliases = [ ] ;
268
+ classInfo . aliases = new Set ( ) ;
269
269
}
270
270
} ,
271
271
272
- AssignmentExpression : function ( node ) {
272
+ AssignmentExpression ( node ) {
273
273
if ( ! classInfo ) {
274
274
return ;
275
275
}
@@ -281,7 +281,7 @@ module.exports = {
281
281
node . right . type === 'ObjectExpression'
282
282
) {
283
283
// Find the nearest function expression containing this assignment.
284
- var fn = node ;
284
+ let fn = node ;
285
285
while ( fn . type !== 'FunctionExpression' && fn . parent ) {
286
286
fn = fn . parent ;
287
287
}
@@ -300,14 +300,14 @@ module.exports = {
300
300
}
301
301
} ,
302
302
303
- VariableDeclarator : function ( node ) {
303
+ VariableDeclarator ( node ) {
304
304
if ( ! classInfo || ! node . init ) {
305
305
return ;
306
306
}
307
307
handleAssignment ( node . id , node . init ) ;
308
308
} ,
309
309
310
- MemberExpression : function ( node ) {
310
+ MemberExpression ( node ) {
311
311
if ( ! classInfo ) {
312
312
return ;
313
313
}
@@ -322,13 +322,13 @@ module.exports = {
322
322
}
323
323
} ,
324
324
325
- JSXSpreadAttribute : function ( node ) {
325
+ JSXSpreadAttribute ( node ) {
326
326
if ( classInfo && isStateReference ( node . argument ) ) {
327
327
classInfo = null ;
328
328
}
329
329
} ,
330
330
331
- ExperimentalSpreadProperty : function ( node ) {
331
+ ExperimentalSpreadProperty ( node ) {
332
332
if ( classInfo && isStateReference ( node . argument ) ) {
333
333
classInfo = null ;
334
334
}
0 commit comments