@@ -15,7 +15,8 @@ var annotations = require('../util/annotations');
15
15
// Constants
16
16
// ------------------------------------------------------------------------------
17
17
18
- var DIRECT_PROPS_REGEX = / ^ p r o p s \s * ( \. | \[ ) / ;
18
+ var PROPS_REGEX = / ^ ( p r o p s | n e x t P r o p s ) $ / ;
19
+ var DIRECT_PROPS_REGEX = / ^ ( p r o p s | n e x t P r o p s ) \s * ( \. | \[ ) / ;
19
20
20
21
// ------------------------------------------------------------------------------
21
22
// Rule Definition
@@ -81,6 +82,39 @@ module.exports = {
81
82
return value ;
82
83
}
83
84
85
+ /**
86
+ * Check if we are in a class constructor
87
+ * @return {boolean } true if we are in a class constructor, false if not
88
+ */
89
+ function inConstructor ( ) {
90
+ var scope = context . getScope ( ) ;
91
+ while ( scope ) {
92
+ if ( scope . block && scope . block . parent && scope . block . parent . kind === 'constructor' ) {
93
+ return true ;
94
+ }
95
+ scope = scope . upper ;
96
+ }
97
+ return false ;
98
+ }
99
+
100
+ /**
101
+ * Check if we are in a class constructor
102
+ * @return {boolean } true if we are in a class constructor, false if not
103
+ */
104
+ function inComponentWillReceiveProps ( ) {
105
+ var scope = context . getScope ( ) ;
106
+ while ( scope ) {
107
+ if (
108
+ scope . block && scope . block . parent &&
109
+ scope . block . parent . key && scope . block . parent . key . name === 'componentWillReceiveProps'
110
+ ) {
111
+ return true ;
112
+ }
113
+ scope = scope . upper ;
114
+ }
115
+ return false ;
116
+ }
117
+
84
118
/**
85
119
* Checks if we are using a prop
86
120
* @param {ASTNode } node The AST node being checked.
@@ -92,7 +126,8 @@ module.exports = {
92
126
node . object . type === 'ThisExpression' && node . property . name === 'props'
93
127
) ;
94
128
var isStatelessFunctionUsage = node . object . name === 'props' ;
95
- return isClassUsage || isStatelessFunctionUsage ;
129
+ var isNextPropsUsage = node . object . name === 'nextProps' && inComponentWillReceiveProps ( ) ;
130
+ return isClassUsage || isStatelessFunctionUsage || isNextPropsUsage ;
96
131
}
97
132
98
133
/**
@@ -464,21 +499,6 @@ module.exports = {
464
499
}
465
500
}
466
501
467
- /**
468
- * Check if we are in a class constructor
469
- * @return {boolean } true if we are in a class constructor, false if not
470
- */
471
- function inConstructor ( ) {
472
- var scope = context . getScope ( ) ;
473
- while ( scope ) {
474
- if ( scope . block && scope . block . parent && scope . block . parent . kind === 'constructor' ) {
475
- return true ;
476
- }
477
- scope = scope . upper ;
478
- }
479
- return false ;
480
- }
481
-
482
502
/**
483
503
* Retrieve the name of a property node
484
504
* @param {ASTNode } node The AST node with the property.
@@ -487,8 +507,9 @@ module.exports = {
487
507
function getPropertyName ( node ) {
488
508
var isDirectProp = DIRECT_PROPS_REGEX . test ( sourceCode . getText ( node ) ) ;
489
509
var isInClassComponent = utils . getParentES6Component ( ) || utils . getParentES5Component ( ) ;
490
- var isNotInConstructor = ! inConstructor ( node ) ;
491
- if ( isDirectProp && isInClassComponent && isNotInConstructor ) {
510
+ var isNotInConstructor = ! inConstructor ( ) ;
511
+ var isNotInComponentWillReceiveProps = ! inComponentWillReceiveProps ( ) ;
512
+ if ( isDirectProp && isInClassComponent && isNotInConstructor && isNotInComponentWillReceiveProps ) {
492
513
return void 0 ;
493
514
}
494
515
if ( ! isDirectProp ) {
@@ -561,13 +582,13 @@ module.exports = {
561
582
// let {props: {firstname}} = this
562
583
var thisDestructuring = (
563
584
! hasSpreadOperator ( node . id . properties [ i ] ) &&
564
- ( node . id . properties [ i ] . key . name === 'props' || node . id . properties [ i ] . key . value === 'props' ) &&
585
+ ( PROPS_REGEX . test ( node . id . properties [ i ] . key . name ) || PROPS_REGEX . test ( node . id . properties [ i ] . key . value ) ) &&
565
586
node . id . properties [ i ] . value . type === 'ObjectPattern'
566
587
) ;
567
588
// let {firstname} = props
568
589
var directDestructuring =
569
- node . init . name === 'props' &&
570
- ( utils . getParentStatelessComponent ( ) || inConstructor ( ) )
590
+ PROPS_REGEX . test ( node . init . name ) &&
591
+ ( utils . getParentStatelessComponent ( ) || inConstructor ( ) || inComponentWillReceiveProps ( ) )
571
592
;
572
593
573
594
if ( thisDestructuring ) {
@@ -600,7 +621,10 @@ module.exports = {
600
621
usedPropTypes . push ( {
601
622
name : name ,
602
623
allNames : allNames ,
603
- node : ! isDirectProp && ! inConstructor ( node ) ? node . parent . property : node . property
624
+ node : (
625
+ ! isDirectProp && ! inConstructor ( ) && ! inComponentWillReceiveProps ( ) ? node . parent . property :
626
+ node . property
627
+ )
604
628
} ) ;
605
629
break ;
606
630
case 'destructuring' :
@@ -612,7 +636,7 @@ module.exports = {
612
636
613
637
var currentNode = node ;
614
638
allNames = [ ] ;
615
- while ( currentNode . property && currentNode . property . name !== 'props' ) {
639
+ while ( currentNode . property && ! PROPS_REGEX . test ( currentNode . property . name ) ) {
616
640
allNames . unshift ( currentNode . property . name ) ;
617
641
currentNode = currentNode . object ;
618
642
}
@@ -813,8 +837,8 @@ module.exports = {
813
837
// let {firstname} = props
814
838
var directDestructuring =
815
839
destructuring &&
816
- node . init . name === 'props' &&
817
- ( utils . getParentStatelessComponent ( ) || inConstructor ( ) )
840
+ PROPS_REGEX . test ( node . init . name ) &&
841
+ ( utils . getParentStatelessComponent ( ) || inConstructor ( ) || inComponentWillReceiveProps ( ) )
818
842
;
819
843
820
844
if ( ! thisDestructuring && ! directDestructuring ) {
0 commit comments