@@ -9,7 +9,6 @@ const values = require('object.values');
99const astUtil = require ( './ast' ) ;
1010const componentUtil = require ( './componentUtil' ) ;
1111const testReactVersion = require ( './version' ) . testReactVersion ;
12- const ast = require ( './ast' ) ;
1312const eslintUtil = require ( './eslint' ) ;
1413
1514const getScope = eslintUtil . getScope ;
@@ -164,7 +163,7 @@ function isInLifeCycleMethod(node, checkAsyncSafeLifeCycles) {
164163 */
165164function isSetStateUpdater ( node ) {
166165 const unwrappedParentCalleeNode = astUtil . isCallExpression ( node . parent )
167- && ast . unwrapTSAsExpression ( node . parent . callee ) ;
166+ && astUtil . unwrapTSAsExpression ( node . parent . callee ) ;
168167
169168 return unwrappedParentCalleeNode
170169 && unwrappedParentCalleeNode . property
@@ -181,7 +180,7 @@ function isPropArgumentInSetStateUpdater(context, node, name) {
181180 while ( scope ) {
182181 const unwrappedParentCalleeNode = scope . block
183182 && astUtil . isCallExpression ( scope . block . parent )
184- && ast . unwrapTSAsExpression ( scope . block . parent . callee ) ;
183+ && astUtil . unwrapTSAsExpression ( scope . block . parent . callee ) ;
185184 if (
186185 unwrappedParentCalleeNode
187186 && unwrappedParentCalleeNode . property
@@ -215,7 +214,7 @@ function isInClassComponent(context, node) {
215214function isThisDotProps ( node ) {
216215 return ! ! node
217216 && node . type === 'MemberExpression'
218- && ast . unwrapTSAsExpression ( node . object ) . type === 'ThisExpression'
217+ && astUtil . unwrapTSAsExpression ( node . object ) . type === 'ThisExpression'
219218 && node . property . name === 'props' ;
220219}
221220
@@ -239,7 +238,7 @@ function hasSpreadOperator(context, node) {
239238 * @returns {boolean }
240239 */
241240function isPropTypesUsageByMemberExpression ( context , node , utils , checkAsyncSafeLifeCycles ) {
242- const unwrappedObjectNode = ast . unwrapTSAsExpression ( node . object ) ;
241+ const unwrappedObjectNode = astUtil . unwrapTSAsExpression ( node . object ) ;
243242
244243 if ( isInClassComponent ( context , node ) ) {
245244 // this.props.*
@@ -260,7 +259,7 @@ function isPropTypesUsageByMemberExpression(context, node, utils, checkAsyncSafe
260259 return false ;
261260 }
262261 // props.* in function component
263- return unwrappedObjectNode . name === 'props' && ! ast . isAssignmentLHS ( node ) ;
262+ return unwrappedObjectNode . name === 'props' && ! astUtil . isAssignmentLHS ( node ) ;
264263}
265264
266265/**
@@ -321,109 +320,91 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
321320 let name ;
322321 let allNames ;
323322 let properties ;
324- switch ( node . type ) {
325- case 'OptionalMemberExpression' :
326- case 'MemberExpression' :
327- name = getPropertyName ( context , node , utils , checkAsyncSafeLifeCycles ) ;
328- if ( name ) {
329- allNames = parentNames . concat ( name ) ;
330- if (
331- // Match props.foo.bar, don't match bar[props.foo]
332- node . parent . type === 'MemberExpression'
333- && node . parent . object === node
334- ) {
335- markPropTypesAsUsed ( node . parent , allNames ) ;
336- }
337- // Handle the destructuring part of `const {foo} = props.a.b`
338- if (
339- node . parent . type === 'VariableDeclarator'
340- && node . parent . id . type === 'ObjectPattern'
341- ) {
342- node . parent . id . parent = node . parent ; // patch for bug in eslint@4 in which ObjectPattern has no parent
343- markPropTypesAsUsed ( node . parent . id , allNames ) ;
344- }
345-
346- // const a = props.a
347- if (
348- node . parent . type === 'VariableDeclarator'
349- && node . parent . id . type === 'Identifier'
350- ) {
351- propVariables . set ( node . parent . id . name , allNames ) ;
352- }
353- // Do not mark computed props as used.
354- type = name !== '__COMPUTED_PROP__' ? 'direct' : null ;
323+ if ( astUtil . isMemberExpression ( node ) ) {
324+ name = getPropertyName ( context , node , utils , checkAsyncSafeLifeCycles ) ;
325+ if ( name ) {
326+ allNames = parentNames . concat ( name ) ;
327+ const parent = node . parent ;
328+ if (
329+ // Match props.foo.bar, don't match bar[props.foo]
330+ parent . type === 'MemberExpression'
331+ && 'object' in parent
332+ && parent . object === node
333+ ) {
334+ markPropTypesAsUsed ( parent , allNames ) ;
355335 }
356- break ;
357- case 'ArrowFunctionExpression' :
358- case 'FunctionDeclaration' :
359- case 'FunctionExpression' : {
360- if ( node . params . length === 0 ) {
361- break ;
336+ // Handle the destructuring part of `const {foo} = props.a.b`
337+ if (
338+ astUtil . isVariableDeclarator ( parent )
339+ && parent . id . type === 'ObjectPattern'
340+ ) {
341+ parent . id . parent = parent ; // patch for bug in eslint@4 in which ObjectPattern has no parent
342+ markPropTypesAsUsed ( parent . id , allNames ) ;
343+ }
344+
345+ // const a = props.a
346+ if (
347+ astUtil . isVariableDeclarator ( parent )
348+ && parent . id . type === 'Identifier'
349+ ) {
350+ propVariables . set ( parent . id . name , allNames ) ;
362351 }
352+ // Do not mark computed props as used.
353+ type = name !== '__COMPUTED_PROP__' ? 'direct' : null ;
354+ }
355+ } else if ( astUtil . isFunctionLike ( node ) ) {
356+ if ( node . params . length > 0 ) {
363357 type = 'destructuring' ;
364358 const propParam = isSetStateUpdater ( node ) ? node . params [ 1 ] : node . params [ 0 ] ;
365359 properties = propParam . type === 'AssignmentPattern'
366360 ? propParam . left . properties
367361 : propParam . properties ;
368- break ;
369362 }
370- case 'ObjectPattern' :
371- type = 'destructuring' ;
372- properties = node . properties ;
373- break ;
374- case 'TSEmptyBodyFunctionExpression' :
375- break ;
376- default :
377- throw new Error ( `${ node . type } ASTNodes are not handled by markPropTypesAsUsed` ) ;
363+ } else if ( astUtil . isObjectPattern ( node ) ) {
364+ type = 'destructuring' ;
365+ properties = node . properties ;
366+ } else if ( node . type !== 'TSEmptyBodyFunctionExpression' ) {
367+ throw new Error ( `${ node . type } ASTNodes are not handled by markPropTypesAsUsed` ) ;
378368 }
379369
380370 const component = components . get ( utils . getParentComponent ( node ) ) ;
381371 const usedPropTypes = ( component && component . usedPropTypes ) || [ ] ;
382372 let ignoreUnusedPropTypesValidation = ( component && component . ignoreUnusedPropTypesValidation ) || false ;
383373
384- switch ( type ) {
385- case 'direct' : {
386- // Ignore Object methods
387- if ( name in Object . prototype ) {
388- break ;
389- }
390-
374+ if ( type === 'direct' ) {
375+ // Ignore Object methods
376+ if ( ! ( name in Object . prototype ) ) {
391377 const reportedNode = node . property ;
392378 usedPropTypes . push ( {
393379 name,
394380 allNames,
395381 node : reportedNode ,
396382 } ) ;
397- break ;
398383 }
399- case 'destructuring' : {
400- for ( let k = 0 , l = ( properties || [ ] ) . length ; k < l ; k ++ ) {
401- if ( hasSpreadOperator ( context , properties [ k ] ) || properties [ k ] . computed ) {
402- ignoreUnusedPropTypesValidation = true ;
403- break ;
404- }
405- const propName = ast . getKeyValue ( context , properties [ k ] ) ;
384+ } else if ( type === 'destructuring' ) {
385+ for ( let k = 0 , l = ( properties || [ ] ) . length ; k < l ; k ++ ) {
386+ if ( hasSpreadOperator ( context , properties [ k ] ) || properties [ k ] . computed ) {
387+ ignoreUnusedPropTypesValidation = true ;
388+ break ;
389+ }
390+ const propName = astUtil . getKeyValue ( context , properties [ k ] ) ;
406391
407- if ( ! propName || properties [ k ] . type !== 'Property' ) {
408- break ;
409- }
392+ if ( ! propName || properties [ k ] . type !== 'Property' ) {
393+ break ;
394+ }
410395
411- usedPropTypes . push ( {
412- allNames : parentNames . concat ( [ propName ] ) ,
413- name : propName ,
414- node : properties [ k ] ,
415- } ) ;
396+ usedPropTypes . push ( {
397+ allNames : parentNames . concat ( [ propName ] ) ,
398+ name : propName ,
399+ node : properties [ k ] ,
400+ } ) ;
416401
417- if ( properties [ k ] . value . type === 'ObjectPattern' ) {
418- markPropTypesAsUsed ( properties [ k ] . value , parentNames . concat ( [ propName ] ) ) ;
419- } else if ( properties [ k ] . value . type === 'Identifier' ) {
420- propVariables . set ( properties [ k ] . value . name , parentNames . concat ( propName ) ) ;
421- }
402+ if ( properties [ k ] . value . type === 'ObjectPattern' ) {
403+ markPropTypesAsUsed ( properties [ k ] . value , parentNames . concat ( [ propName ] ) ) ;
404+ } else if ( properties [ k ] . value . type === 'Identifier' ) {
405+ propVariables . set ( properties [ k ] . value . name , parentNames . concat ( propName ) ) ;
422406 }
423- break ;
424407 }
425- default :
426- break ;
427408 }
428409
429410 components . set ( component ? component . node : node , {
@@ -484,7 +465,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
484465
485466 return {
486467 VariableDeclarator ( node ) {
487- const unwrappedInitNode = ast . unwrapTSAsExpression ( node . init ) ;
468+ const unwrappedInitNode = astUtil . unwrapTSAsExpression ( node . init ) ;
488469
489470 // let props = this.props
490471 if ( isThisDotProps ( unwrappedInitNode ) && isInClassComponent ( context , node ) && node . id . type === 'Identifier' ) {
@@ -559,7 +540,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils)
559540 return ;
560541 }
561542
562- const propVariable = propVariables . get ( ast . unwrapTSAsExpression ( node . object ) . name ) ;
543+ const propVariable = propVariables . get ( astUtil . unwrapTSAsExpression ( node . object ) . name ) ;
563544 if ( propVariable ) {
564545 markPropTypesAsUsed ( node , propVariable ) ;
565546 }
0 commit comments