@@ -31,36 +31,32 @@ const messages = {
31
31
module . exports = {
32
32
meta : {
33
33
docs : {
34
- description :
35
- 'Disallow missing displayName in a React component definition' ,
34
+ description : 'Disallow missing displayName in a React component definition' ,
36
35
category : 'Best Practices' ,
37
36
recommended : true ,
38
37
url : docsUrl ( 'display-name' ) ,
39
38
} ,
40
39
41
40
messages,
42
41
43
- schema : [
44
- {
45
- type : 'object' ,
46
- properties : {
47
- ignoreTranspilerName : {
48
- type : 'boolean' ,
49
- } ,
50
- checkContextObjects : {
51
- type : 'boolean' ,
52
- } ,
42
+ schema : [ {
43
+ type : 'object' ,
44
+ properties : {
45
+ ignoreTranspilerName : {
46
+ type : 'boolean' ,
47
+ } ,
48
+ checkContextObjects : {
49
+ type : 'boolean' ,
53
50
} ,
54
- additionalProperties : false ,
55
51
} ,
56
- ] ,
52
+ additionalProperties : false ,
53
+ } ] ,
57
54
} ,
58
55
59
56
create : Components . detect ( ( context , components , utils ) => {
60
57
const config = context . options [ 0 ] || { } ;
61
58
const ignoreTranspilerName = config . ignoreTranspilerName || false ;
62
- const checkContextObjects = ( config . checkContextObjects || false )
63
- && testReactVersion ( context , '>= 16.3.0' ) ;
59
+ const checkContextObjects = ( config . checkContextObjects || false ) && testReactVersion ( context , '>= 16.3.0' ) ;
64
60
65
61
const contextObjects = new Map ( ) ;
66
62
@@ -80,12 +76,10 @@ module.exports = {
80
76
* @returns {boolean } True if React.forwardRef is nested inside React.memo, false if not.
81
77
*/
82
78
function isNestedMemo ( node ) {
83
- return (
84
- astUtil . isCallExpression ( node )
79
+ return astUtil . isCallExpression ( node )
85
80
&& node . arguments
86
81
&& astUtil . isCallExpression ( node . arguments [ 0 ] )
87
- && utils . isPragmaComponentWrapper ( node )
88
- ) ;
82
+ && utils . isPragmaComponentWrapper ( node ) ;
89
83
}
90
84
91
85
/**
@@ -121,40 +115,46 @@ module.exports = {
121
115
* @returns {boolean } True if component has a name, false if not.
122
116
*/
123
117
function hasTranspilerName ( node ) {
124
- const namedObjectAssignment = node . type === 'ObjectExpression'
118
+ const namedObjectAssignment = (
119
+ node . type === 'ObjectExpression'
125
120
&& node . parent
126
121
&& node . parent . parent
127
122
&& node . parent . parent . type === 'AssignmentExpression'
128
- && ( ! node . parent . parent . left . object
123
+ && (
124
+ ! node . parent . parent . left . object
129
125
|| node . parent . parent . left . object . name !== 'module'
130
- || node . parent . parent . left . property . name !== 'exports' ) ;
131
- const namedObjectDeclaration = node . type === 'ObjectExpression'
126
+ || node . parent . parent . left . property . name !== 'exports'
127
+ )
128
+ ) ;
129
+ const namedObjectDeclaration = (
130
+ node . type === 'ObjectExpression'
132
131
&& node . parent
133
132
&& node . parent . parent
134
- && node . parent . parent . type === 'VariableDeclarator' ;
135
- const namedClass = ( node . type === 'ClassDeclaration' || node . type === 'ClassExpression' )
133
+ && node . parent . parent . type === 'VariableDeclarator'
134
+ ) ;
135
+ const namedClass = (
136
+ ( node . type === 'ClassDeclaration' || node . type === 'ClassExpression' )
136
137
&& node . id
137
- && ! ! node . id . name ;
138
+ && ! ! node . id . name
139
+ ) ;
138
140
139
- const namedFunctionDeclaration = ( node . type === 'FunctionDeclaration'
140
- || node . type === 'FunctionExpression' )
141
+ const namedFunctionDeclaration = (
142
+ ( node . type === 'FunctionDeclaration' || node . type === 'FunctionExpression' )
141
143
&& node . id
142
- && ! ! node . id . name ;
144
+ && ! ! node . id . name
145
+ ) ;
143
146
144
- const namedFunctionExpression = astUtil . isFunctionLikeExpression ( node )
147
+ const namedFunctionExpression = (
148
+ astUtil . isFunctionLikeExpression ( node )
145
149
&& node . parent
146
- && ( node . parent . type === 'VariableDeclarator'
147
- || node . parent . type === 'Property'
148
- || node . parent . method === true )
149
- && ( ! node . parent . parent
150
- || ! componentUtil . isES5Component ( node . parent . parent , context ) ) ;
150
+ && ( node . parent . type === 'VariableDeclarator' || node . parent . type === 'Property' || node . parent . method === true )
151
+ && ( ! node . parent . parent || ! componentUtil . isES5Component ( node . parent . parent , context ) )
152
+ ) ;
151
153
152
154
if (
153
- namedObjectAssignment
154
- || namedObjectDeclaration
155
+ namedObjectAssignment || namedObjectDeclaration
155
156
|| namedClass
156
- || namedFunctionDeclaration
157
- || namedFunctionExpression
157
+ || namedFunctionDeclaration || namedFunctionExpression
158
158
) {
159
159
return true ;
160
160
}
@@ -199,31 +199,29 @@ module.exports = {
199
199
}
200
200
201
201
function isIdentifierShadowed ( node , identifierName ) {
202
- while ( node && node . parent ) {
203
- node = node . parent ;
202
+ let currentNode = node ;
203
+ while ( currentNode && currentNode . parent ) {
204
+ currentNode = currentNode . parent ;
204
205
if (
205
- node . type === 'FunctionDeclaration'
206
- || node . type === 'FunctionExpression'
207
- || node . type === 'ArrowFunctionExpression'
206
+ currentNode . type === 'FunctionDeclaration'
207
+ || currentNode . type === 'FunctionExpression'
208
+ || currentNode . type === 'ArrowFunctionExpression'
208
209
) {
209
210
break ;
210
211
}
211
212
}
212
213
213
- if ( ! node || ! node . body ) {
214
+ if ( ! currentNode || ! currentNode . body ) {
214
215
return false ;
215
216
}
216
217
217
- return hasVariableDeclaration ( node . body , identifierName ) ;
218
+ return hasVariableDeclaration ( currentNode . body , identifierName ) ;
218
219
}
219
-
220
220
/**
221
- *
222
- * Check is current component shadowed
223
- * @param {ASTNode } node The AST node being checked.
224
- * @returns {boolean } True if component has a name, false if not.
221
+ * Checks whether the component wrapper (e.g. React.memo or forwardRef) is shadowed in the current scope.
222
+ * @param {ASTNode } node - The CallExpression AST node representing a potential component wrapper.
223
+ * @returns {boolean } True if the wrapper identifier (e.g. 'React', 'memo', 'forwardRef') is shadowed, false otherwise.
225
224
*/
226
-
227
225
function isShadowedComponent ( node ) {
228
226
if ( ! node || node . type !== 'CallExpression' ) {
229
227
return false ;
@@ -253,10 +251,7 @@ module.exports = {
253
251
return {
254
252
ExpressionStatement ( node ) {
255
253
if ( checkContextObjects && isCreateContext ( node ) ) {
256
- contextObjects . set ( node . expression . left . name , {
257
- node,
258
- hasDisplayName : false ,
259
- } ) ;
254
+ contextObjects . set ( node . expression . left . name , { node, hasDisplayName : false } ) ;
260
255
}
261
256
} ,
262
257
VariableDeclarator ( node ) {
@@ -320,10 +315,7 @@ module.exports = {
320
315
if ( ignoreTranspilerName || ! hasTranspilerName ( node ) ) {
321
316
// Search for the displayName declaration
322
317
node . properties . forEach ( ( property ) => {
323
- if (
324
- ! property . key
325
- || ! propsUtil . isDisplayNameDeclaration ( property . key )
326
- ) {
318
+ if ( ! property . key || ! propsUtil . isDisplayNameDeclaration ( property . key ) ) {
327
319
return ;
328
320
}
329
321
markDisplayNameAsDeclared ( node ) ;
@@ -338,10 +330,7 @@ module.exports = {
338
330
return ;
339
331
}
340
332
341
- if (
342
- node . arguments . length > 0
343
- && astUtil . isFunctionLikeExpression ( node . arguments [ 0 ] )
344
- ) {
333
+ if ( node . arguments . length > 0 && astUtil . isFunctionLikeExpression ( node . arguments [ 0 ] ) ) {
345
334
// Skip over React.forwardRef declarations that are embedded within
346
335
// a React.memo i.e. React.memo(React.forwardRef(/* ... */))
347
336
// This means that we raise a single error for the call to React.memo
0 commit comments